我遇到问题并得到不正确的结果。我想统计每年有休假日期和死亡日期的记录,并将它们显示在一张表中。
这是我到目前为止的查询:
select year(leavedate) as leave_year, count(year(leavedate)) as cnt_leave , count(year(DeceasedDate)) as cnt_dod
from clients
where leavedate is not null and DeceasedDate is not null
group by year(leavedate),year(DeceasedDate)
order by 1 desc
这是我想要的目标:
+------+-----------+---------+
| Year | Cnt_leave | Cnt_dod |
+------+-----------+---------+
| 2018 | 542 | 5685 |
| 2017 | 8744 | 5622 |
| 2016 | 556 | 325 |
| etc | | |
+------+-----------+---------+
我应该在两个单独的select语句中执行还是可以在一个语句中执行? 感谢您的反馈!
答案 0 :(得分:1)
我会做的:
with
l as (
select year(leavedate) as y, count(*) as c
from clients
group by year(leavedate)
),
d as (
select year(deceaseddate) as y, count(*) as c
from clients
group by year(deceaseddate)
)
select
coalesce(l.y, d.y) as year,
coalesce(l.c, 0) as cnt_leave,
coalesce(d.c, 0) as cnt_dod
from l
full outer join d on l.y = d.y
order by coalesce(l.y, d.y) desc
答案 1 :(得分:0)
如果我理解,您正在寻找这样的东西:
select year(leavedate) as leave_year, sum(case leavedate when null then 0 else 1 end) as cnt_leave,
sum(case DeceasedDate when null then 0 else 1 end) as cnt_dod
from clients
where leavedate is not null or DeceasedDate is not null
group by year(leavedate)
order by 1 desc
答案 2 :(得分:0)
您需要分两步计算,因为Year(LeaveDate)
与Year(DeceasedDate)
无关;但是您可以通过一些CTE构造来组合这些SELECT。
实际上,有(至少)两种方法可以做到这一点,不确定哪种方法会表现更好;您需要尝试找出最适合您数据的方法。
SELECT client_id = 1, LeaveDate = Convert(datetime, '20080118'), DeceasedDate = Convert(datetime, '20090323')
INTO #test
UNION ALL SELECT client_id = 2, LeaveDate = '20100118', DeceasedDate = '20100323'
UNION ALL SELECT client_id = 3, LeaveDate = '20100118', DeceasedDate = '20120323'
;WITH src
AS (SELECT *
FROM #test
WHERE LeaveDate IS NOT NULL
AND DeceasedDate IS NOT NULL),
leave
AS (SELECT yr = Year(LeaveDate), cnt = COUNT(*) FROM src GROUP BY Year(LeaveDate)),
deceased
AS (SELECT yr = Year(DeceasedDate), cnt = COUNT(*) FROM src GROUP BY Year(DeceasedDate))
SELECT yr = ISNULL(l.yr, d.yr),
cntLeaveDate = ISNULL(l.cnt, 0),
cntDeceasedDate = ISNULL(d.cnt, 0)
FROM leave l
FULL OUTER JOIN deceased d
ON d.yr = l.yr
ORDER BY 1 DESC
;WITH src
AS (SELECT *
FROM #test
WHERE LeaveDate IS NOT NULL
AND DeceasedDate IS NOT NULL),
years
AS (SELECT DISTINCT yr = Year(LeaveDate) FROM src
UNION -- Do not UNION ALL here, you want to avoid doubles!
SELECT DISTINCT yr = Year(DeceasedDate) FROM src)
SELECT yr,
cntLeaveDate = SUM ( CASE WHEN Year(LeaveDate) = yr THEN 1 ELSE 0 END),
cntDeceasedDate = SUM ( CASE WHEN Year(DeceasedDate) = yr THEN 1 ELSE 0 END)
FROM years, #test
WHERE LeaveDate IS NOT NULL
AND DeceasedDate IS NOT NULL
GROUP BY yr
ORDER BY 1 DESC
DROP TABLE #test
答案 3 :(得分:0)
我会为此使用apply
。 。 。我认为这是最简单的解决方案:
select year(dte) as year, sum(isleave) as num_leaves, sum(isdeceased) as numdeceased
from clients c cross apply
(values (leavedate, 1, 0),
(deceaseddate, 0, 1)
) v(dte, isleave, isdeceased)
where dte is not null
group by year(dte)
order by 1 desc;
答案 4 :(得分:-1)
根据您的评论,您所需要做的就是删除where子句并限制分组依据。
select
year(leavedate) as leave_year,
count(year(leavedate)) as cnt_leave ,
count(year(DeceasedDate)) as cnt_dod
from clients
--where leavedate is not null and DeceasedDate is not null
group by year(leavedate) --,year(DeceasedDate)
--order by 1 desc
或者,如果您的数据在任一列中都可以有NULL
,我在上面假设,因此省略了您想要的where
子句:
select
coalesce(year(leavedate),year(DeceasedDate)) as the_year,
count(year(leavedate)) as cnt_leave ,
count(year(DeceasedDate)) as cnt_dod
from clients
--where leavedate is not null and DeceasedDate is not null
group by coalesce(year(leavedate),year(DeceasedDate))
--order by 1 desc
这里是例子:
declare @clients table (leavedate date null, DeceasedDate date null)
insert into @clients
values
('20180101',NULL)
,(null,'20170101')
,('20150101','20150101')
select
year(leavedate) as leave_year,
count(year(leavedate)) as cnt_leave ,
count(year(DeceasedDate)) as cnt_dod
from @clients
--where leavedate is not null and DeceasedDate is not null
group by year(leavedate) --,year(DeceasedDate)
--order by 1 desc
select
coalesce(year(leavedate),year(DeceasedDate)) as the_year,
count(year(leavedate)) as cnt_leave ,
count(year(DeceasedDate)) as cnt_dod
from @clients
--where leavedate is not null and DeceasedDate is not null
group by coalesce(year(leavedate),year(DeceasedDate))
--order by 1 desc