根据应用于列的case语句选择一个不同的行

时间:2013-02-05 20:53:32

标签: sql tsql

我无法弄清楚sql查询(使用MS Sql Server)。我正在尝试从数据集中检索单行,其中具有一个id的项可以包含多行。让我失望的部分是正确的行应该基于“层次结构”。我试图在这个问题上提出一个案例陈述。

一些示例数据:

Id           Class       Date
100          Red         2012-12-12
100          Blue        2012-12-31
200          Red         2012-10-31
300          Green       2012-04-04
300          Blue        2011-09-01

我想根据Class的值返回一行。

Case When Red Then
    Date 
Case When Blue Then 
    Date
Case When Green Then 
    Date 
Else
    ''

我的最终数据集应如下所示:

Id           Class       Date
100          Red         2012-12-12
200          Red         2012-10-31
300          Blue        2011-09-01

因此,如果其中一个重复行的值为Red,请首先使用该行中的日期。然后是蓝色,然后是绿色。

整天都在处理这个问题,玩弄子查询,分组,拥有,案例陈述,派生表。我的sql技能非常生疏,因为已经有一段时间了。

关于我应该采取的方向的任何提示?

3 个答案:

答案 0 :(得分:5)

你可以试试这个

;WITH cte AS
  (
    SELECT Id, Class, Date,
      row_number() OVER (PARTITION BY Id
                         ORDER BY CASE Class
                                  WHEN 'Red' THEN 1
                                  WHEN 'Blue' THEN 2
                                  WHEN 'Green' THEN 3
                                  ELSE 4 END) as rn
    FROM MyTable
   )

SELECT Id, Class, Date
FROM cte
WHERE rn = 1

答案 1 :(得分:0)

尝试:

select id, class, date
  from TABLE
 where class = COLOR
   and date  = (select min(date) from TABLE where class = COLOR)

答案 2 :(得分:0)

我喜欢@bobs查询,它在TSQL数据库上运行良好。

这只是做同样事情的另一种方式,可能对其他具有公用表表达式但不具有相同行号语法的SQL数据库更具可移植性;

;WITH cte AS
(SELECT *, CASE Class WHEN 'Red' THEN 1 WHEN 'Blue' THEN 2
                      WHEN 'Green' THEN 3 ELSE 4 END c FROM myTable)

SELECT b1.Id, b1.Class, b1.Date
FROM cte b1 
LEFT JOIN cte b2 
  ON b1.Id = b2.Id AND b1.c > b2.c
WHERE b2.Class IS NULL

An SQLfiddle to test with