将同一列的今天和从今天开始的总数结合起来会产生一个 sql 查询

Posted

技术标签:

【中文标题】将同一列的今天和从今天开始的总数结合起来会产生一个 sql 查询【英文标题】:combine today and total previous from today of that same column results in one sql query 【发布时间】:2012-10-12 06:17:26 【问题描述】:
declare @temp table (ddate datetime)

insert @temp
select DATEDIFF(d,0,CONVERT(smalldatetime,'09/30/2012')  -Number)
from master..spt_values
where type='p' and number < DatePart(d,'09/30/2012')
order by 1

DECLARE @DeptCode int =1 

--显示特定日期数据

select   ComplaintMedia_Abbri,
ddate,COUNT(ComplaintMedia)  as c
from    Complaint 
INNER JOIN @temp 
ON convert(datetime,convert(varchar(10),ComplaintDate,101),101)=convert(datetime,convert(varchar(10),ddate,101),101)        
WHERE isnull(Receivedby_Dept,Relatesto_Dept)=1     
group by ComplaintMedia_Abbri,ddate
order by ddate,ComplaintMedia_Abbri

-- 显示截至日期的特定日期数据运行总计

select   ComplaintMedia_Abbri,ddate,
    COUNT(ComplaintMedia_Abbri)  as c
    from    Complaint 

    INNER JOIN @temp 
    ON convert(datetime,convert(varchar(10),ComplaintDate,101),101)<=convert(datetime,convert(varchar(10),ddate,101),101)       

    WHERE isnull(Receivedby_Dept,Relatesto_Dept)=1     
    group by ComplaintMedia_Abbri,ddate

我想在一个 sql 查询结果中显示截至日期和今天(那天)记录的运行总计..​​...

在加入时有两个不同的条件。

预期的结果应该是这样的

编辑: 我可以通过使用这些查询并加入它们来实现此结果,但我想在一个查询而不是两个查询中完成此任务

我目前的方式可以在这里查看。抱歉这么长的问题,但我认为实际上有必要理解问题..

declare @temp table (ddate datetime)

insert @temp
select DATEDIFF(d,0,CONVERT(smalldatetime,'09/30/2012')  -Number)
from master..spt_values
where type='p' and number < DatePart(d,'09/30/2012')
order by 1

--select * from @temp

SELECT * FROM 

        (select ddate,ISNULL(L,0) AS Letter,
          ISNULL(P,0) AS Phone,
          ISNULL(E,0) AS Email,
          ISNULL(W,0) AS WEB 
          FROM 
          (
            select   ComplaintMedia_Abbri,
          ddate,COUNT(ComplaintMedia)  as c
            from    Complaint 
            INNER JOIN @temp 
            ON convert(datetime,convert(varchar(10),ComplaintDate,101),101)=convert(datetime,convert(varchar(10),ddate,101),101)        
            WHERE isnull(Receivedby_Dept,Relatesto_Dept)=1     
            group by ComplaintMedia_Abbri,ddate
    ) p 

    pivot (SUM(c) FOR ComplaintMedia_Abbri IN (E,W,L,P)) AS pvt 

    ) AS [A]

    INNER JOIN 

    (
    select ddate,ISNULL(L,0) AS LetterTot,
      ISNULL(P,0) AS PhoneTot,
      ISNULL(E,0) AS EmailTot,
      ISNULL(W,0) AS WEBTot
      FROM 
      (

    select   ComplaintMedia_Abbri,ddate,
    COUNT(ComplaintMedia_Abbri)  as c
    from    Complaint 

    INNER JOIN @temp 
    ON convert(datetime,convert(varchar(10),ComplaintDate,101),101)<=convert(datetime,convert(varchar(10),ddate,101),101)       

    WHERE isnull(Receivedby_Dept,Relatesto_Dept)=1     
    group by ComplaintMedia_Abbri,ddate
    ) p 

   pivot (SUM(c) FOR ComplaintMedia_Abbri IN (E,W,L,P)) AS pvt



    ) AS [B]

   ON A.ddate=B.ddate

   order by A.ddate

【问题讨论】:

您的数据是什么样的,预期的结果是什么? 预期列是第二部分和第三部分查询结果... @t-clausen.dk 嘿问题更新了当前查询和当前结果,但它们来自两个不同的查询,我想将这两个合并为一个以提高此存储过程的速度。 我认为 MS Sql 服务器中没有默认功能来获取运行(累积)总数。我曾经***.com/questions/11664142/… 发布过同样的问题。在 PL/Sql 中这很容易。我猜你正在寻找同样的东西。 它已添加到 SQL Server 2012,但不是 2008。SUM(Letter) OVER (ORDER BY ddate RANGE UNBOUNDED PRECEDING) LetterTotal - 请参阅 sqlfiddle.com/#!6/1e69d/2 【参考方案1】:

我已经修改了评论中给出的 SQL Fiddle,如果你已经有了每日总数,它将给你想要的输出:

http://www.sqlfiddle.com/#!6/09168/2

DECLARE @startDate datetime
DECLARE @endDate datetime

SELECT @startDate = '2012-10-08'
SELECT @endDate = '2012-10-12'

SELECT
    DT1.ddate,
    DT1.phone,
    DT1.letter,
    DT1.email,
    DT1.web,
    SUM(DT2.phone) phoneTotal,
    SUM(DT2.letter) letterTotal,
    SUM(DT2.email) emailTotal,
    SUM(DT2.web) webTotal 
  FROM
    DailyTotals DT1
    LEFT JOIN DailyTotals DT2 ON DT1.ddate >= DT2.ddate AND DT2.ddate >= @startDate
  WHERE
    DT1.ddate <= @endDate
  GROUP BY
  DT1.ddate,
  DT1.phone,
  DT1.letter,
  DT1.email,
  DT1.web

如果您想使其成为一个语句,您需要将 DailyTotals 替换为您的子查询,该子查询为您提供每日总计。不过,我建议创建一个名为 DailyTotals 的视图并使用它。

编辑:

您可以使用 CTE 而不是临时表来生成日期范围。我已经修改了你说的完整查询,你说它可以加入 CTE 而不是 @temp。我没有办法测试它。如果这不起作用,请使用您的架构创建一个 SLQ Fiddle,我会再试一次。

WITH Dates AS
(
    SELECT CONVERT(date, MIN(ComplaintTime)) AS ddate,
    MAX(ComplaintTime) as EndDate
    FROM
      Complaints
    UNION ALL
    SELECT DATEADD(DAY, 1, ddate), EndDate
    FROM Dates
    WHERE DATEADD(DAY, 1, ddate) <= EndDate
    )

SELECT * FROM 

        (select ddate,ISNULL(L,0) AS Letter,
          ISNULL(P,0) AS Phone,
          ISNULL(E,0) AS Email,
          ISNULL(W,0) AS WEB 
          FROM 
          (
            select   ComplaintMedia_Abbri,
          ddate,COUNT(ComplaintMedia)  as c
            from    Complaint 
            INNER JOIN Dates
            ON convert(date,ComplaintDate)=ddate OPTION (MAXRECURSION 500)
            WHERE isnull(Receivedby_Dept,Relatesto_Dept)=1     
            group by ComplaintMedia_Abbri,ddate
    ) p 

    pivot (SUM(c) FOR ComplaintMedia_Abbri IN (E,W,L,P)) AS pvt 

    ) AS [A]

    INNER JOIN 

    (
    select ddate,ISNULL(L,0) AS LetterTot,
      ISNULL(P,0) AS PhoneTot,
      ISNULL(E,0) AS EmailTot,
      ISNULL(W,0) AS WEBTot
      FROM 
      (

    select   ComplaintMedia_Abbri,ddate,
    COUNT(ComplaintMedia_Abbri)  as c
    from    Complaint 

    INNER JOIN Dates OPTION (MAXRECURSION 0)
    ON CONVERT(date,ComplaintDate) <= ddate OPTION (MAXRECURSION 0)

    WHERE isnull(Receivedby_Dept,Relatesto_Dept)=1     
    group by ComplaintMedia_Abbri,ddate
    ) p 

   pivot (SUM(c) FOR ComplaintMedia_Abbri IN (E,W,L,P)) AS pvt



    ) AS [B]

   ON A.ddate=B.ddate

   order by A.ddate

【讨论】:

嘿,你做得很好,但你的解决方案的问题是它只给我运行总计,我不是在寻找运行总计,我正在寻找该列之前的日值和总和那一天…… 语句终止。在语句完成之前,最大递归 100 已用完。 :( @rahularyansharma 再次编辑。每次加入日期后,请参阅 OPTION (MAXRECURSION 0)。默认情况下,SQL Server 将 CTE 的最大递归级别设置为 100 以防止无限循环。如果您将其设置为 0,那么在您确定您的 CTE 正确之前,对循环数没有限制,这是非常危险的。我已将 1 设置为 500,将 1 设置为无限。我建议您将其设置为等于投诉表中最大日期和最小日期之间的天数。一旦你满意它可以正常工作,你可以将它们都设置为 0 如果您没有意识到 CTE 的每次递归都会将第二天添加到结果中,直到达到最大日期。因此,您的投诉表中最旧和最新记录之间的间隔超过 100 天。

以上是关于将同一列的今天和从今天开始的总数结合起来会产生一个 sql 查询的主要内容,如果未能解决你的问题,请参考以下文章

第1493期 React 的今天和明天(图文版)第一部分

从今天开始,博客复活啦

php 按Anywhere Elementor小部件中的今天和未来日期排序

从今天开始好好学数据结构02栈与队列

安全学习之路Day1

Visual Studio:iOS 模拟器从今天开始消失