有点复杂的代码波纹管为您提供了解决方案。
我必须说 - 在现有场景中,重复使用条形码的人会强制您的解决方案总是在整个销售历史中向后看,以便在给定的环境中设计“重用事件的顺序”。
你最好不要重复使用条码或非规范化的“重用秩序”作为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