我有一个查询,可以在一天内检查数据库中的多个客户条形码扫描。这个报告效果很好,但是我想添加另一篇文章。我想在输出中包含一列“Times Scanned”。但是,因为我使用“SUM”,所以它不会在1行上多次列出。例如,如果发现条形码“1234”被扫描两次,我希望它被扫描的时间(tickets.dtcreated)在“times Scanned”列中列为一个输出。
这是我目前的输出:
Barcode DtCreatedDate Number of Scans
1234 1/1/2013 2
1235 1/1/2013 2
1563 1/2/2013 3
以下是我希望输出看起来像的内容(请记住,“Times Scanned”应该只显示多次扫描发生当天的时间(DTcreateddate):
Barcode DtCreatedDate Number of Scans Times Scanned
1234 1/1/2013 2 11:15AM, 12:15PM
1235 1/1/2013 2 9:00AM, 4:00PM
1563 1/2/2013 3 8:05AM, 8:08AM, 5:50PM
我的当前查询位于
之下 SELECT Customers.sBarcode, CAST(FLOOR(CAST(Tickets.dtCreated AS FLOAT)) AS DATETIME) AS dtCreatedDate, COUNT(Customers.sBarcode) AS [Number of Scans]
FROM Tickets INNER JOIN
Customers ON Tickets.lCustomerID = Customers.lCustomerID
WHERE (Tickets.dtCreated BETWEEN @startdate AND @enddate) AND (Tickets.dblTotal <= 0)
GROUP BY Customers.sBarcode, CAST(FLOOR(CAST(Tickets.dtCreated AS FLOAT)) AS DATETIME)
HAVING (COUNT(*) > 1)
ORDER BY dtCreatedDate
答案 0 :(得分:1)
您无法使用SUM
,但可以使用FOR XML PATH
。将其添加到SELECT列表中:
SELECT ...,
STUFF(( SELECT ', ' + RIGHT(convert(varchar, sub.dtCreated, 100), 7)
FROM Tickets sub
WHERE sub.Ticket_ID = Tickets.Ticket_ID
FOR XML PATH('')
), 1, 2, '' )
AS [Times Scanned]
FROM Tickets
JOIN ...
这里的想法是使用RIGHT(convert(varchar, sub.dtCreated, 100), 7)
来获取格式化的时间,然后使用FOR XML PATH
连接它们,同时删除带有STUFF
答案 1 :(得分:0)
我建议编写一个函数来创建调用的时间列表,然后在查询中调用该函数。
答案 2 :(得分:0)
SELECT Customers.sBarcode, @startdate AS startdate, @enddate AS enddate,
CAST(FLOOR(CAST(Tickets.dtCreated AS FLOAT)) AS DATETIME) AS dtCreatedDate,
COUNT(Customers.sBarcode) AS [Number of Scans],
[Times Scanned] = MAX(STUFF((SELECT ',' + RIGHT(CONVERT(varchar, sub.dtCreated, 100), 7)
FROM Tickets AS sub
WHERE sub.Ticket_id = Tickets.Ticket_ID
FOR XML PATH, TYPE).value('.[1]', 'nvarchar(max)'), 1, 1, ''))
FROM Tickets INNER JOIN Customers ON Tickets.lCustomerID = Customers.lCustomerID
WHERE(Tickets.dtCreated BETWEEN @startdate AND @enddate) AND (Tickets.dblTotal <= 0)
GROUP BY Customers.sBarcode, CAST(FLOOR(CAST(Tickets.dtCreated AS FLOAT)) AS DATETIME), Tickets.Ticket_ID
HAVING (COUNT(*) > 1)
ORDER BY dtCreatedDate
答案 3 :(得分:0)
如果您正在使用Oracle(并且它是最近的版本),您可以使用LISTAGG()函数
LISTAGG(TimesScanned, ', ') WITHIN GROUP (ORDER BY TimesScanned)
其他数据库有时会有聚合函数;看到这个问题:Concatenate many rows into a single text string?