将同一列的今天和从今天开始的总数结合起来会产生一个 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 查询的主要内容,如果未能解决你的问题,请参考以下文章