如何使用SUM基于查询结果获取查询详细信息

时间:2013-02-05 16:01:31

标签: sql sql-server sql-server-2008 tsql

我有一个查询,可以在一天内检查数据库中的多个客户条形码扫描。这个报告效果很好,但是我想添加另一篇文章。我想在输出中包含一列“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

4 个答案:

答案 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?