MIN(DATE) 在 SQL 服务器中不工作
MIN(DATE) not working in SQL Server
我正在使用 SSMS 查询 SQL Server 2012。我需要 NPH table 中最早开始日期的记录。如果我有一个客户的行具有相同的开始日期,我会得到一行。但是对于具有不同开始日期的行的客户,我根本得不到任何结果。为什么它不从 PLACEMENTHISTORY table 中带回最小(开始日期)?
select distinct lsf.CLIENTNUMBER
,nph.ENDDATE
,nph.STARTDATE
from legalstatusform lsf
left join PLACEMENTHISTORY nph on nph.CLIENTNUMBER = lsf.clientnumber
and (nph.STARTDATE = (select min(startdate) from PLACEMENTHISTORY x
where x.CLIENTNUMBER = nph.CLIENTNUMBER))
where nph.ENDDATE >= '2017-05-01'
and nph.ENDDATE <= '2017-05-31'
and nph.CLIENTNUMBER = '2001'
group by lsf.CLIENTNUMBER, lsf.ENDDATE, nph.STARTDATE, nph.ENDDATE
这个逻辑根本没有给我任何结果
如果我注释掉 min(startdate) 逻辑,我会得到该客户端的 3 行数据。开始日期为 1/31/2017、4/11/2017 和 5/10/2017。因此,使用 min(startdate) 逻辑,为什么我只得到开始日期为 1/31/2017 的第 1 行?
select distinct
几乎不适合 group by
.
您的问题是 where
子句中的条件。这些将外部连接变成内部连接。试试这个:
select distinct lsf.CLIENTNUMBER, nph.ENDDATE, nph.STARTDATE
from legalstatusform lsf left join
PLACEMENTHISTORY nph
on nph.CLIENTNUMBER = lsf.clientnumber and
nph.STARTDATE = (select min(startdate)
from PLACEMENTHISTORY x
where x.CLIENTNUMBER = nph.CLIENTNUMBER)
) and
nph.ENDDATE >= '2017-05-01' and
nph.ENDDATE <= '2017-05-31'
where lsf.CLIENTNUMBER = '2001';
备注:
- 您可能需要子查询中
ENDDATE
的条件。
- 我会 window 函数而不是这种形式的查询。
- 如果
CLIENTNUMBER
是一个数字,那么 '2001'
不应该有引号。
因为你的 MIN() 子查询没有这个条件:
where nph.ENDDATE >= '2017-05-01'
and nph.ENDDATE <= '2017-05-31'
运行 只是子查询
select min(startdate) from PLACEMENTHISTORY
where x.CLIENTNUMBER = '2001'
并查看具有 MIN() 开始日期的行是否与外部查询中的过滤器匹配。
与其使用子查询(并解析 table 两次)不如尝试使用 CTE。排序最终可能同样昂贵,具体取决于您的索引:
WITH CTE AS(
SELECT lsf.CLIENTNUMBER,
nph.ENDDATE,
nph.STARTDATE,
ROW_NUMBER() OVER (PARTITION BY lsf.CLIENTNUMBER ORDER BY nph.STARTDATE) AS RN
FROM legalstatusform lsf
LEFT JOIN PLACEMENTHISTORY nph ON nph.CLIENTNUMBER = lsf.clientnumber
WHERE nph.ENDDATE >= '2017-05-01'
AND nph.ENDDATE <= '2017-05-31'
AND nph.CLIENTNUMBER = '2001'
GROUP BY lsf.CLIENTNUMBER, lsf.ENDDATE, nph.STARTDATE, nph.ENDDATE)
SELECT *
FROM CTE
WHERE RN = 1;
我正在使用 SSMS 查询 SQL Server 2012。我需要 NPH table 中最早开始日期的记录。如果我有一个客户的行具有相同的开始日期,我会得到一行。但是对于具有不同开始日期的行的客户,我根本得不到任何结果。为什么它不从 PLACEMENTHISTORY table 中带回最小(开始日期)?
select distinct lsf.CLIENTNUMBER
,nph.ENDDATE
,nph.STARTDATE
from legalstatusform lsf
left join PLACEMENTHISTORY nph on nph.CLIENTNUMBER = lsf.clientnumber
and (nph.STARTDATE = (select min(startdate) from PLACEMENTHISTORY x
where x.CLIENTNUMBER = nph.CLIENTNUMBER))
where nph.ENDDATE >= '2017-05-01'
and nph.ENDDATE <= '2017-05-31'
and nph.CLIENTNUMBER = '2001'
group by lsf.CLIENTNUMBER, lsf.ENDDATE, nph.STARTDATE, nph.ENDDATE
这个逻辑根本没有给我任何结果
如果我注释掉 min(startdate) 逻辑,我会得到该客户端的 3 行数据。开始日期为 1/31/2017、4/11/2017 和 5/10/2017。因此,使用 min(startdate) 逻辑,为什么我只得到开始日期为 1/31/2017 的第 1 行?
select distinct
几乎不适合 group by
.
您的问题是 where
子句中的条件。这些将外部连接变成内部连接。试试这个:
select distinct lsf.CLIENTNUMBER, nph.ENDDATE, nph.STARTDATE
from legalstatusform lsf left join
PLACEMENTHISTORY nph
on nph.CLIENTNUMBER = lsf.clientnumber and
nph.STARTDATE = (select min(startdate)
from PLACEMENTHISTORY x
where x.CLIENTNUMBER = nph.CLIENTNUMBER)
) and
nph.ENDDATE >= '2017-05-01' and
nph.ENDDATE <= '2017-05-31'
where lsf.CLIENTNUMBER = '2001';
备注:
- 您可能需要子查询中
ENDDATE
的条件。 - 我会 window 函数而不是这种形式的查询。
- 如果
CLIENTNUMBER
是一个数字,那么'2001'
不应该有引号。
因为你的 MIN() 子查询没有这个条件:
where nph.ENDDATE >= '2017-05-01'
and nph.ENDDATE <= '2017-05-31'
运行 只是子查询
select min(startdate) from PLACEMENTHISTORY
where x.CLIENTNUMBER = '2001'
并查看具有 MIN() 开始日期的行是否与外部查询中的过滤器匹配。
与其使用子查询(并解析 table 两次)不如尝试使用 CTE。排序最终可能同样昂贵,具体取决于您的索引:
WITH CTE AS(
SELECT lsf.CLIENTNUMBER,
nph.ENDDATE,
nph.STARTDATE,
ROW_NUMBER() OVER (PARTITION BY lsf.CLIENTNUMBER ORDER BY nph.STARTDATE) AS RN
FROM legalstatusform lsf
LEFT JOIN PLACEMENTHISTORY nph ON nph.CLIENTNUMBER = lsf.clientnumber
WHERE nph.ENDDATE >= '2017-05-01'
AND nph.ENDDATE <= '2017-05-31'
AND nph.CLIENTNUMBER = '2001'
GROUP BY lsf.CLIENTNUMBER, lsf.ENDDATE, nph.STARTDATE, nph.ENDDATE)
SELECT *
FROM CTE
WHERE RN = 1;