获取TSQL中WHERE子句上每个值的GROUP BY的聚合结果

时间:2018-03-07 08:53:03

标签: sql sql-server sql-server-2008 tsql

我在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

表很大,因此需要考虑性能。任何想法如何进行?

3 个答案:

答案 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