Sql server 减少两个联合查询的输出,当前生成的行太多

Sql server 减少两个联合查询的输出,当前生成的行太多,sql-server,merge,union,Sql Server,Merge,Union,SQL Server:这是我的基本查询。我不知道如何正确地使这个结果只显示每个商店/日期的一行,这两个查询分别填写在第3列和第4列。现在,结果是每个存储/日期有2行,相反的列中有NULL。每个门店/日期只能有一行,第三列偶尔会有空 DECLARE @START DATETIME, @END DATETIME SET @END = CAST(CAST(GETDATE() AS DATE) AS DATETIME) + '03:00' SET @START = @END - 7 SELECT

SQL Server:这是我的基本查询。我不知道如何正确地使这个结果只显示每个商店/日期的一行,这两个查询分别填写在第3列和第4列。现在,结果是每个存储/日期有2行,相反的列中有NULL。每个门店/日期只能有一行,第三列偶尔会有空

DECLARE @START DATETIME, @END DATETIME
SET @END   = CAST(CAST(GETDATE() AS DATE) AS DATETIME) + '03:00'
SET @START = @END - 7

SELECT 
    @START [From], @END [To]

SELECT 
    DivisionName, DateClosed, COUNT(OrderId) AS PREDATED, NULL AS DAYOF 
FROM 
    (SELECT 
         o.OrderId, DivisionName, DateCreated, 
         CONVERT(Date, DateClosed) [DateClosed]   
     FROM 
         POS.Orders o WITH(NOLOCK)
     JOIN 
         POS.OrderDetails od WITH(NOLOCK) ON o.OrderId = od.OrderId
     JOIN 
         Directory.Divisions d WITH(NOLOCK) ON o.DivisionId = d.DivisionId
     WHERE 
         DateClosed BETWEEN @START AND @END AND DateCreated < @START) t
 GROUP BY 
     DivisionName, DateClosed

 UNION

 SELECT 
     DivisionName, DateClosed, NULL AS PREDATED, COUNT(OrderID) AS DAYOF
 FROM 
     (SELECT 
          o.OrderId, DivisionName, DateCreated, 
          CONVERT(Date,DateClosed)[DateClosed]
      FROM 
          POS.Orders o WITH(NOLOCK)
      JOIN 
          POS.OrderDetails od WITH(NOLOCK) ON o.OrderId = od.OrderId
      JOIN 
          Directory.Divisions d WITH(NOLOCK) ON o.DivisionId = d.DivisionId
      WHERE 
          DateClosed BETWEEN @START AND @END AND DateCreated >= @START) s
GROUP BY 
    DivisionName, DateClosed

您可以使用如下结构:

;WITH t as (
    <your query>
) 
SELECT DivisionName, DateClosed, MAX(PREDATED) AS PREDATED, MAX(DAYOF) AS DAYOF 
FROM t 
GROUP BY DivisionName, DateClosed;
SELECT 
     DivisionName, CONVERT(Date, DateClosed) [DateClosed],
     COUNT(CASE WHEN DateClosed BETWEEN @START AND @END AND DateCreated < @START THEN 0 END) AS PREDATED,
     COUNT(CASE WHEN DateClosed BETWEEN @START AND @END AND DateCreated >= @START THEN 0 END) AS DAYOF
 FROM 
     POS.Orders o WITH(NOLOCK)
 JOIN 
     POS.OrderDetails od WITH(NOLOCK) ON o.OrderId = od.OrderId
 JOIN 
     Directory.Divisions d WITH(NOLOCK) ON o.DivisionId = d.DivisionId
 GROUP BY 
     DivisionName, DateClosed
我没有您的示例数据,但您可以使用如下查询:

;WITH t as (
    <your query>
) 
SELECT DivisionName, DateClosed, MAX(PREDATED) AS PREDATED, MAX(DAYOF) AS DAYOF 
FROM t 
GROUP BY DivisionName, DateClosed;
SELECT 
     DivisionName, CONVERT(Date, DateClosed) [DateClosed],
     COUNT(CASE WHEN DateClosed BETWEEN @START AND @END AND DateCreated < @START THEN 0 END) AS PREDATED,
     COUNT(CASE WHEN DateClosed BETWEEN @START AND @END AND DateCreated >= @START THEN 0 END) AS DAYOF
 FROM 
     POS.Orders o WITH(NOLOCK)
 JOIN 
     POS.OrderDetails od WITH(NOLOCK) ON o.OrderId = od.OrderId
 JOIN 
     Directory.Divisions d WITH(NOLOCK) ON o.DivisionId = d.DivisionId
 GROUP BY 
     DivisionName, DateClosed

只是使用;使用t作为分区名称,DateClosed,MaxPreded作为Preded,MAXDAYOF作为DAYOF,按分区名称,DateClosed;;从t组中选择;。您可以简化查询,只需为完整日期范围选择一次数据集,然后在计数中使用case语句来选择要计数的日期范围。当您重复这样的代码时,通常会有更好的方法。如果你感兴趣的话,我会发布更多的细节;有了t,上述建议就完美地发挥了作用。现在,我需要仔细阅读并理解为什么,以便在将来复制这项技术。如果你加上这个作为答案,我会投赞成票。这看起来非常有希望,但由于中间的东西没有排除范围之外的订单,导致了100到数千行。我尝试将WHERE DateClosed移到。。。。在GROUP BY之前更进一步,这很有效,但这导致12000行正确的单个结果,比我开始时更糟糕,试图让我的两个原始求和结果合并得更多。为什么你认为第二个解决方案更糟糕?由于性能问题,第二个更好!?还有可读性问题!?是的,第二个在视觉上和逻辑上看起来都很棒。但结果是相同日期范围的12000行。第一个使用我的原始查询和分号语法,将我的160个交错行减少到92个合并行,非常完美。