使用GROUP BY ALL重写查询

时间:2018-04-12 15:33:14

标签: sql sql-server tsql group-by sql-server-2014

Microsoft已弃用GROUP BY ALL,虽然该查询现在可能有效,但我希望能够在将来验证此查询,以便将来进行SQL升级。

目前,我的查询是:

SELECT       qt.QueueName AS [Queue] ,
             COUNT ( qt.QueueName ) AS [#ofUnprocessedEnvelopes] ,
             COUNT (   CASE WHEN dq.AssignedToUserID = 0 THEN 1
                            ELSE NULL
                       END
                   ) AS [#ofUnassignedEnvelopes] ,
             MIN ( dq.DocumentDate ) AS [OldestEnvelope]
FROM         dbo.VehicleReg_Documents_QueueTypes AS [qt]
             LEFT OUTER JOIN dbo.VehicleReg_Documents_Queue AS [dq] ON dq.QueueID = qt.QueueTypeID
WHERE        dq.IsProcessed = 0
             AND dq.PageNumber = 1
GROUP BY ALL qt.QueueName
ORDER BY     qt.QueueName ASC;

结果数据集:



<table><tbody><tr><td>Queue</td><td>#ofUnprocessedEnvelopes</td><td>#ofUnassignedEnvelopes</td><td>OldestEnvelope</td></tr><tr><td>Cancellations</td><td>0</td><td>0</td><td>NULL</td></tr><tr><td>Dealer</td><td>26</td><td>17</td><td>2018-04-06</td></tr><tr><td>Matched to Registration</td><td>93</td><td>82</td><td>2018-04-04</td></tr><tr><td>New Registration</td><td>166</td><td>140</td><td>2018-03-21</td></tr><tr><td>Remaining Documents</td><td>2</td><td>2</td><td>2018-04-04</td></tr><tr><td>Renewals</td><td>217</td><td>0</td><td>2018-04-03</td></tr><tr><td>Transfers</td><td>296</td><td>245</td><td>2018-03-30</td></tr><tr><td>Writebacks</td><td>53</td><td>46</td><td>2018-04-09</td></tr></tbody></table>
&#13;
&#13;
&#13;

我尝试过使用CTE和UNION的各种版本,但我无法正确生成结果集 - 没有计数的记录将不会显示,或者我将显示重复的记录。

有关如何在没有GROUP BY ALL的情况下完成此工作的任何建议吗?

以下是我尝试使用UNION CTE的一次尝试:

;WITH QueueTypes ( QueueTypeID, QueueName )
AS ( SELECT QueueTypeID ,
            QueueName
     FROM   dbo.VehicleReg_Documents_QueueTypes )
SELECT   qt.QueueName AS [Queue] ,
         COUNT ( qt.QueueName ) AS [#ofUnprocessedEnvelopes] ,
         COUNT (   CASE WHEN dq.AssignedToUserID = 0 THEN 1
                        ELSE NULL
                   END
               ) AS [#ofUnassignedEnvelopes] ,
         CONVERT ( VARCHAR (8), MIN ( dq.DocumentDate ), 1 ) AS [OldestEnvelope]
FROM     QueueTypes AS qt
         LEFT OUTER JOIN dbo.VehicleReg_Documents_Queue AS dq ON dq.QueueID = qt.QueueTypeID
WHERE    dq.IsProcessed = 0
         AND dq.PageNumber = 1
GROUP BY qt.QueueName
UNION ALL
SELECT   qt.QueueName AS [Queue] ,
         COUNT ( qt.QueueName ) AS [#ofUnprocessedEnvelopes] ,
         COUNT (   CASE WHEN dq.AssignedToUserID = 0 THEN 1
                        ELSE NULL
                   END
               ) AS [#ofUnassignedEnvelopes] ,
         CONVERT ( VARCHAR (8), MIN ( dq.DocumentDate ), 1 ) AS [OldestEnvelope]
FROM     QueueTypes AS qt
         LEFT OUTER JOIN dbo.VehicleReg_Documents_Queue AS dq ON dq.QueueID = qt.QueueTypeID
GROUP BY qt.QueueName

但结果并不接近正确:

Result Set

2 个答案:

答案 0 :(得分:1)

我认为将'GROUP BY ALL'纳入更符合ANSI标准的最佳推论是CASE声明。在不知道你的数据的情况下,很难确定这是不是1:1,但我认为这是在球场。

import time

browserObj.get(url)

time.sleep(3)

soup = BeautifulSoup(browserObj.page_source, 'lxml')

这有点丑陋,因为每个聚合都必须在case语句中包含WHERE条件,但至少你是未来的证据。

答案 1 :(得分:1)

您当前的查询无法正常工作,因为当您在外部联接表VehicleReg_Documents_Queue时,您会忽略WHERE子句中的所有外部联接行,因此您就是这样的地方仅仅是内心的联系。您可能需要考虑将条件移至ON子句或立即将其作为内部联接。

将队列类型和队列加入队列ID 队列类型ID,但在dq.QueueID = qt.QueueTypeID上,这也很奇怪。这就像加入员工和地址的员工编号匹配门牌号码。至少这就是它的样子。

(那么为什么你的队列类型表有一个队列名?队列表不应该包含队列名吗?但这不是关于你的查询,而是关于你的数据模型。)

GROUP BY ALL表示:“请将所有QueueNames提供给我们,即使WHERE条款解除它们。我看到了两种查询的可能性:

  1. 你确实想要一个外连接。然后没有WHERE子句,您只需制作此GROUP BY qt.QueueName
  2. 您不需要外部联接。然后我们希望表中的每个QueueName都有一行,我们可能无法将GROUP BY ALL qt.QueueName更改为GROUP BY qt.QueueName
  3. 在第二种情况下,我们希望所有QueueNames首先和外部加入您的查询:

    select 
      qn.QueueName AS [Queue],
      q.[#ofUnassignedEnvelopes],
      q.[OldestEnvelope]
    FROM (select distinct QueueName from VehicleReg_Documents_QueueTypes) qn
    LEFT JOIN
    (
      SELECT       qt.QueueName,
                   COUNT ( qt.QueueName ) AS [#ofUnprocessedEnvelopes] ,
                   COUNT (   CASE WHEN dq.AssignedToUserID = 0 THEN 1
                                  ELSE NULL
                             END
                         ) AS [#ofUnassignedEnvelopes] ,
                   MIN ( dq.DocumentDate ) AS [OldestEnvelope]
      FROM         dbo.VehicleReg_Documents_QueueTypes AS [qt]
      JOIN         dbo.VehicleReg_Documents_Queue AS [dq] ON dq.QueueID = qt.QueueTypeID
      WHERE        dq.IsProcessed = 0
                   AND dq.PageNumber = 1
    ) q ON q.QueueName = qn.QueueName
    GROUP BY ALL qn.QueueName
    ORDER BY     qn.QueueName ASC;