SQL:最新Null之后的最早日期如果存在

时间:2014-03-27 15:55:24

标签: sql date

使用T-Sql我希望在最新的null之后返回最小日期(如果存在),并且只返回没有空值的任何产品的最小日期。 表:

DateSold        Product
12/31/2012      A
1/31/2013   
2/28/2013       A
3/31/2013       A
4/30/2013       A
5/31/2013   
6/30/2013       A
7/31/2013       A
8/31/2013       A
9/30/2013       A
12/31/2012      B
1/31/2013       B
2/28/2013       B
3/31/2013       B
4/30/2013       B
5/31/2013       B
6/30/2013       B
7/31/2013       B
8/31/2013       B
9/30/2013       B

对于产品“A”6/30/2013是期​​望的回报,而产品“B”12/31/2012是期​​望的。 结果:

MinDateSold  Product
6/30/2013       A
12/31/2012      B

任何解决方案都将受到极大的赞赏。谢谢。

2 个答案:

答案 0 :(得分:0)

一种方法是计算给定值在给定行之前出现的NULL值的数量。这将范围分成组。对于每个组,请采用最短日期。并且,找到每种产品的最大最小日期:

select product, minDate
from (select product, NumNulls, min(DateSold) as minDate,
             row_number() over (partition by product order by min(DateSold) desc
                               ) as seqnum
      from (select t.*,
                   (select count(*)
                    from table t2
                    where t2.product is null and t2.DateSold <= t.DateSold
                   ) as NumNulls
            from table t
           ) t
      group by Product, NumNUlls
     ) t
where seqnum = 1;

在您的数据中,某个范围内没有混合使用不同的产品,因此这种查询假设也是如此。

答案 1 :(得分:0)

这对我来说,如果涉及到一个GROUP,那么你怎么知道NULL是否在A或B产品的运行中?我意识到这可能不完全是你所追求的,但我希望无论如何它都会有所帮助。

WITH DATA_IN AS (
SELECT 1 as grp,
       convert(DateTime,'12/31/2012') as d_Date,
      'A' AS d_ch
  UNION ALL
SELECT 1, '1/31/2013',   NULL UNION ALL
SELECT 1, '2/28/2013',    'A' UNION ALL
SELECT 1, '3/31/2013',    'A' UNION ALL
SELECT 1, '4/30/2013',    'A' UNION ALL
SELECT 1, '5/31/2013',   NULL UNION ALL
SELECT 1, '6/30/2013',    'A' UNION ALL
SELECT 1, '7/31/2013',    'A' UNION ALL
SELECT 1, '8/31/2013',    'A' UNION ALL
SELECT 1, '9/30/2013',    'A' UNION ALL

SELECT 2, '12/31/2012',   'B' UNION ALL
SELECT 2, '1/31/2013',    'B' UNION ALL
SELECT 2, '2/28/2013',    'B' UNION ALL
SELECT 2, '3/31/2013',    'B' UNION ALL
SELECT 2, '4/30/2013',    'B' UNION ALL
SELECT 2, '5/31/2013',    'B' UNION ALL
SELECT 2, '6/30/2013',    'B' UNION ALL
SELECT 2, '7/31/2013',    'B' UNION ALL
SELECT 2, '8/31/2013',    'B' UNION ALL
SELECT 2, '9/30/2013',    'B'
)
SELECT
  grp as YourGroup,
  (SELECT Min(d_date) -- first date after...
   FROM DATA_IN
   WHERE d_date>
    Coalesce( -- either the latest NULL
     (SELECT max(d_Date)
      FROM DATA_IN d2
      WHERE d2.grp=d1.grp AND d2.d_ch IS NULL
     )
     , '1/1/1901'  -- or a base date if no NULLs
    )
  ) as MinDateSold
FROM DATA_IN d1
GROUP BY grp

结果:

1   2013-06-30 00:00:00.000
2   2012-12-31 00:00:00.000
相关问题