选择最少的日期,或在SQL中为空

时间:2018-10-15 10:48:36

标签: sql sql-server

这太过简单了,但是:

我有一张桌子,如下所示:

CREATE TABLE Table1
    ([ID] int, [USER] varchar(5), [DATE] date)
;

INSERT INTO Table1
    ([ID], [USER], [DATE])
VALUES
    (1, 'A', '2018-10-01'),
    (2, 'A', '2018-09-01'),
    (3, 'A', NULL),
    (4, 'B', '2018-05-03'),
    (5, 'B', '2017-04-01'),
    (6, 'C', NULL)
;

对于每个用户,我希望检索DATE变量最小的整行详细信息。

SELECT T.USER FROM TABLE1 T
WHERE T.DATE = (SELECT MIN(DATE) FROM TABLE1 T1 WHERE T1.USER = T.USER)

效果很好,但是在实例中没有一行带有填充的DATE字段,会有一行带有NULL的行,就像上面表格的最后一行一样,我也希望选择。

所以在这种情况下,我的理想输出是:

(2, 'A', '2018-09-01'),
(5, 'B', '2017-04-01'),
(6, 'C', NULL)

SQL提琴:http://www.sqlfiddle.com/#!9/df42b5/6

我认为可以使用EXCLUDE语句来完成某些事情,但是它很快就会变得复杂。

4 个答案:

答案 0 :(得分:2)

您可以尝试使用row_number()

https://github.com/kelproject/pykube/blob/master/pykube/objects.py

    select * from
    (select *, row_number() over(partition by [user] order by [user],case when 
     [date] is null then 0 else 1 end desc,[date]) as rn
     from Table1)x where rn=1

答案 1 :(得分:1)

通过min()函数使用联合和与合作相关的子查询

     CREATE TABLE Table1 (ID int, usr varchar(50), DATE1 date)
;

INSERT INTO Table1 VALUES
    (1, 'A', '2018-10-01'),
    (2, 'A', '2018-09-01'),
    (3, 'A', NULL),
    (4, 'B', '2018-05-03'),
    (5, 'B', '2017-04-01'),
    (6, 'C', NULL)
;



select * from Table1 t  where 
   DATE1= (select min(date1) from Table1 t1 where t1.usr=t.usr
         ) and date1 is not null
           union
select * from Table1 t where date1 is  null
and t.usr not in ( select usr from Table1 where date1 is not null)

DEMO

ID  usr     DATE1
2   A   01/09/2018 00:00:00
5   B   01/04/2017 00:00:00
6   C   

答案 2 :(得分:0)

您可以使用通用表表达式:

;WITH chronology AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY [USER] 
            ORDER BY ISNULL([DATE], '2900-01-01') ASC
        ) Idx
    FROM TABLE1
)
SELECT ID, [USER], [DATE]  
FROM chronology
WHERE Idx=1;

在此解决方案中使用CTE可以简化查询,从而提高其可读性,可维护性和可扩展性。此外,我希望这种方法在性能方面是最佳的。

答案 3 :(得分:0)

您可以使用GROUP BY和JOIN输出所需的结果。

select t.Id
    , x.[User]
    , x.[MinDate] as [Date]
from
(select [User]
   , min([Date]) as MinDate
from table1
group by [User]) x
   inner join table1 t on t.[User] = x.[User] and (t.[Date] = x.[MinDate] or x.[MinDate] is null)