有點複雜的代碼波紋管爲您提供瞭解決方案。
我必須說 - 在現有場景中,重複使用條形碼的人會強制您的解決方案總是在整個銷售歷史中向後看,以便在給定的環境中設計「重用事件的順序」。
你最好不要重複使用條碼或非規範化的「重用秩序」作爲Ticketsdetails
新列。
享受...
SET NOCOUNT ON
go
--------------------------------------------------------------------------------
-- Isolate the card sale/redeem events (we are not interested in the books)
--
-- note the 'barcode_reuse_count' column
--------------------------------------------------------------------------------
DECLARE @price_per_book MONEY
SET @price_per_book = 5
SELECT
Ticket_Number, barcode, date_created,
--
CASE WHEN Description = 'Card Sale' THEN 1
ELSE 0
END AS is_event_of_sale /* is this an event of card sale? */,
--
CASE WHEN
Description = 'Card Sale' THEN (TotalAmount * 2)/@price_per_book /* Well, $5 HAS to mean TWO books... */
ELSE TotalAmount/@price_per_book
END AS Credit_Or_Debit_As_Books,
--
CONVERT(INT, NULL) AS barcode_reuse_order
INTO #card_events
FROM Ticketsdetails
WHERE Detail_Type_ID = '11'
go
--------------------------------------------------------------------------------
-- For each ticket, identify the ticket where the card in its 'barcode reuse'
-- incarnation was sold (although there should be one, and only one, barcode per
-- Ticket_Number, the query allows for more than one...)
--
-- Then, set 'barcode_reuse_order'
--------------------------------------------------------------------------------
WITH card_sale_event AS
(
SELECT card_event.Ticket_Number, card_event.barcode, MAX(card_event_sale.Ticket_Number) AS Ticket_Number_Of_Sale
FROM
#card_events card_event
INNER JOIN #card_events card_event_sale
ON(
card_event_sale.barcode = card_event.barcode
AND card_event_sale.is_event_of_sale = 1
AND card_event_sale.Ticket_Number <= card_event.Ticket_Number
)
GROUP BY card_event.Ticket_Number, card_event.barcode
)
UPDATE card_event
SET
barcode_reuse_order =(
SELECT
COUNT(DISTINCT prev_card_sale_event.Ticket_Number_Of_Sale)
/* card_event_sale may have many Ticket_Number_Of_Sale per barcode, one per Ticket_Number */
FROM card_sale_event prev_card_sale_event
WHERE
prev_card_sale_event.barcode = card_sale_event.barcode
AND prev_card_sale_event.Ticket_Number < card_sale_event.Ticket_Number_Of_Sale
)
FROM
#card_events card_event
INNER JOIN card_sale_event
ON(
card_sale_event.Ticket_Number = card_event.Ticket_Number
AND card_sale_event.barcode = card_event.barcode
)
go
--------------------------------------------------------------------------------
-- Le grand result
--------------------------------------------------------------------------------
SELECT
barcode +
CASE
WHEN barcode_reuse_order > 0 THEN '(' + CONVERT(VARCHAR, barcode_reuse_order + 1) + ')'
ELSE ''
END AS barcode,
--
CONVERT(INT, MAX(date_created)) -
CONVERT(INT, MIN(date_created)) AS Days_between_usage,
--
SUM(Credit_Or_Debit_As_Books) AS Balance
FROM #card_events
GROUP BY
barcode +
CASE
WHEN barcode_reuse_order > 0 THEN '(' + CONVERT(VARCHAR, barcode_reuse_order + 1) + ')'
ELSE ''
END
go
--------------------------------------------------------------------------------
-- Clean-up
--------------------------------------------------------------------------------
DROP TABLE #card_events
go
我用下面的腳本上傳給定數據。
IF EXISTS(SELECT * FROM sys.tables WHERE name = 'Ticketsdetails')
DROP TABLE Ticketsdetails
go
CREATE TABLE Ticketsdetails(
Ticket_Number INT,
Detail_type_ID INT,
Description VARCHAR(32),
Date_Created DATETIME,
TotalAmount MONEY,
Barcode VARCHAR(16)
)
go
insert into Ticketsdetails values(1, 11, 'Card Sale', '20160101', 5, '123')
insert into Ticketsdetails values(1, 1, 'Book', '20160101', 5, NULL)
insert into Ticketsdetails values(1, 11, 'Card Red', '20160101', -5, '123 ')
insert into Ticketsdetails values(2, 1, 'book', '20160105', 5, NULL)
insert into Ticketsdetails values(3, 1, 'book', '20160106', 5, NULL)
insert into Ticketsdetails values(3, 11, 'Card Red', '20160106', -5, '123')
insert into Ticketsdetails values(4, 11, 'Card Sale', '20160107', 5, '124')
insert into Ticketsdetails values(5, 1, 'Book', '20160107', 5, NULL)
insert into Ticketsdetails values(5, 11, 'Card Red', '20160107', -5, '124')
insert into Ticketsdetails values(6, 11, 'Card Sale', '20160108', 5, '123')
insert into Ticketsdetails values(6, 1, 'Book', '20160108', 5, NULL)
insert into Ticketsdetails values(6, 11, 'Card Red', '20160108', -5, '123')
insert into Ticketsdetails values(7, 1, 'Book', '20160109', 5, NULL)
insert into Ticketsdetails values(7, 11, 'Card Red', '20160109', -5, '124')
go
向我解釋更多關於「餘額仍然存在」的業務邏輯。把它作爲第三列而不是另一行可能更容易,但我想這取決於你需要什麼。 –
也是票號。票號如何與其餘數據相關聯? –
我其實只是想編輯我的問題,使其成爲第三列,因爲我試圖通過這個工作。 – Shmewnix