我在SQL Server中有一个表格,格式如下
MType (Integer), MDate (Datetime), Status (SmallInt)
1, 10-05-2018, 1
1, 15-05-2018, 1
2, 25-3-2018, 0
3, 12-01-2018, 1
....
我想为将来的日期获取特定MDate
的MIN MTypes
。如果没有,则应返回MType
,但值为NULL
。
这是我到目前为止所做的事情:
SELECT m.MType,
MIN(m.MDate)
FROM MyTypes m
WHERE m.MType IN ( 1, 2, 3, 4)
AND m.MDate > GETDATE()
AND m.Status = 1
GROUP BY m.MType
显然,上述内容仅返回以下内容:
1, 10-05-2018
由于还有其他行的未来日期和状态等于1。
然而,我想要的结果是:
1, 10-05-2018
2, NULL
3, NULL
4, NULL //this is missing in general from the table. No MType with value 4
表很大,因此需要考虑性能。任何想法如何进行?
答案 0 :(得分:3)
一种方法是将表连接到自身并在ON
子句中过滤日期。
SELECT a.Mtype, MIN(b.MDate)
FROM MyTypes a
LEFT JOIN MyTypes b
ON a.MType = b.MType
AND b.MDate > GETDATE()
AND b.Status = 1
WHERE a.MType IN ( 1, 2, 3)
GROUP BY a.MType
这里是Demo。
答案 1 :(得分:1)
我不知道背后的逻辑是什么,但它似乎使用查找表
SELECT a.MType, l.MDate
FROM
(
values (1),(2),(3),(4)
)a (MType)
LEFT JOIN (
SELECT m.MType,
MIN(m.MDate) MDate
FROM MyTypes m
WHERE m.MDate > GETDATE()
AND m.Status = 1
GROUP BY m.MType
)l on l.MType = a.MType
答案 2 :(得分:0)
使用Windows函数和数字表的联合:
declare @t table (MType int, MDate datetime, [Status] smallint)
Insert into @t values (1, convert(date, '10-05-2018', 103), 1)
,(1, convert(date, '15-05-2018', 103), 1)
,(2, convert(date, '25-03-2018', 103), 0)
,(3, convert(date, '12-01-2018', 103), 1)
Select DISTINCT Mtype
, min(iiF(MDate>getdate() and status = 1, MDate, NUll)) over (Partition By Mtype) as MDate
from ( SELECT TOP 10000 row_number() over(order by t1.number) as MType
, '1900-01-01' as MDate, 0 as [Status]
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
union
Select Mtype, MDate, [Status] from @t
) x
where MType in (1,2,3,4)
order by x.MType