sql - SQL 为 2017 年或 2018 年或 2019 年的列范围内的每一行返回 1
问题描述
我有一个看起来像这样的查询:
SELECT DISTINCT
p.person_ID
,p.Last_Name
,ISNULL(p.Middle_Initial, '') AS Middle
,p.First_Name
,sh.Status_from_date
,sh.Status_thru_date
--(a)
FROM
person p
INNER JOIN
Person_Facilities f ON p.Person_ID = f.Person_ID
LEFT OUTER JOIN
rv_person_status_hist sh ON p.person_ID = sh.person_ID
ORDER BY
Last_Name
返回的数据看起来像这样的东西(暂时忽略 2018 列):
Person_id Last_Name Middle First_Name Status_from_date Status_thru_date 2018
8000 Skywalker Dude Luke Null 2010-01-28 07:38 1
9000 Yoda Phinnius 2017-06-01 00:00 2019-05-31 00:00 1
1000 Lamb Little Mary 2018-07-01 00:00 2020-06-30 00:00 1
2000 Spider Bitsy Itsy 2016-11-01 00:00 2017-06-30 00:00 1
如何添加一列,比如 [2018],如果 status_from_date 到 status_thru_date 在 2018 年,则为 1,否则为 0?
我想在查询的 --(a) 中添加以下内容:
,(SELECT case
when exists
(
select * --
FROM dbo.RV_Person_status_hist
where
status_from_date is not null
and
('1-1-2018' between status_from_date and status_thru_date)
and status_from_date is not null
)
then 1 else 0 end )
AS [2018]
不过,这似乎不起作用。请参阅上表中的 2018 年列。它显示所有返回的 1,并且不排除空值。这很复杂。status_from 和 status_thru 可能与 2018 一起下降,或者 2018 可能在 status_from 和 status_thru 中,它们都应该是 1。
如何排除空值,当状态日期包括 2018 年时如何显示 1?
我查看了range 内的 range,并返回 0 或 1。我不认为我有所有案例,因为范围也重叠。
**更新:我尝试在上面的 --(a) 中添加它,根据下面的潜在答案:
,(SELECT status_from_date, status_thru_date,
case
when datepart(year, status_from_date)='2018'
or datepart(year, status_thru_date)='2018'
or (
status_from_date <= '01/01/2018'
and status_thru_date >= '12/12/2018'
)
then 1
else 0
end) AS [2018]
但我得到了模棱两可的列名'status_from_date'。不明确的列名“status_thru_date”。当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。
有任何想法吗?弄清楚了。
**更新2:这个怎么样?
,(case when (
(
(sh.status_from_date is null or sh.status_from_date <= '2017-01-01') and
(sh.status_thru_date is null or sh.status_thru_date >= '2017-12-31')
)
or
(
(f.status_from_date is null or f.status_from_date <= '2017-01-01') and
(f.status_thru_date is null or f.status_thru_date >= '2017-12-31')
)
or
(
(datepart(year, sh.status_from_date)='2017') or
(datepart(year, sh.status_thru_date)='2017') or
(datepart(year, f.status_from_date)='2017') or
(datepart(year, f.status_from_date)='2017')
)
and
p.Sex='M'
)
then 1 else 0
end) as [2017_Male]
,(case when (
(
(sh.status_from_date is null or sh.status_from_date <= '2017-01-01') and
(sh.status_thru_date is null or sh.status_thru_date >= '2017-12-31')
)
or
(
(f.status_from_date is null or f.status_from_date <= '2017-01-01') and
(f.status_thru_date is null or f.status_thru_date >= '2017-12-31')
)
or
(
(datepart(year, sh.status_from_date)='2017') or
(datepart(year, sh.status_thru_date)='2017') or
(datepart(year, f.status_from_date)='2017') or
(datepart(year, f.status_from_date)='2017')
)
and
p.Sex='F'
)
then 1 else 0
end) as [2017_Female]--------
那个在 2017 年男性和女性列中为以下数据输入 1:status_from: 2014-10-01 和 status_to: 2016-09-30
解决方案
如果你想在 2018 年有任何重叠,那么:
(case when (status_from_date is null or status_from_date < '2019-01-01') and
(status_to_date is null or status_to_date >= '2018-01-01')
then 1 else 0
end) as is_2018
如果您想要全年的重叠:
(case when (status_from_date is null or status_from_date <= '2018-01-01') and
(status_to_date is null or status_to_date >= '2018-12-31')
then 1 else 0
end) as is_2018
推荐阅读
- php - 为什么我的视图部分消失了?
- javascript - html5画布对象绘制
- javascript - 使用 redux 输入的递增和递减计数器
- c++ - 如何读取objdump --disassemble生成的Symboltable,即每一列是什么意思?
- ios - 相机应用程序是否有 iOS 应用程序 URL 方案
- java - Azure function to upload file time out
- javascript - Parcel / ES6:引导功能不起作用
- javascript - 在nodejs中将md5哈希转换为bigint
- javascript - 修改数组以阻止对象嵌套
- c++ - getaddrinfo 与 inet_pton