2

我有一个查询,可以在一天内检查数据库中的多个客户条形码扫描。该报告效果很好,但是我想在其中添加另一篇文章。我想在输出中包含一列“扫描次数”。但是,由于我使用的是“SUM”,它不会在 1 行上多次列出。例如,如果发现条形码“1234”被扫描两次,我希望它被扫描的次数(tickets.dtcreated)作为一个输出列在“扫描次数”列中。

这是我当前的输出:

Barcode    DtCreatedDate     Number of Scans   
    1234          1/1/2013            2            
    1235          1/1/2013            2            
    1563          1/2/2013            3         

这是我希望我的输出看起来像的样子(请记住,“扫描时间”应该只显示发生多次扫描的当天的时间(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

4 回答 4

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

于 2013-02-05T16:19:32.747 回答
0

我建议编写一个函数来创建调用时间列表,然后在查询中调用该函数。

于 2013-02-05T16:13:25.730 回答
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
于 2013-02-05T23:26:29.440 回答
0

如果您使用的是 Oracle(并且它是最近的版本),您可以使用 LISTAGG() 函数

LISTAGG(TimesScanned, ', ') WITHIN GROUP (ORDER BY TimesScanned)

其他数据库有时为此具有聚合函数;看到这个问题:Concatenate many rows into a single text string?

于 2013-05-28T16:12:22.940 回答