SQL组合列

时间:2012-11-23 17:39:11

标签: sql sql-server

我遇到一个问题,我的SQL查询不会删除空值。

我尝试过无数种不同的技巧,但我是新手。

我想要的结果是订单号,后跟状态在一行中出现的日期。

select mo.order_id OrderID,
case when osr.order_status_cd = 120 and osr.create_date is not null then    osr.create_date end as POCreated,
case when osr.order_status_cd = 220 and osr.create_date is not null then osr.create_date end as Ordered,
case when osr.order_status_cd = 300 and osr.create_date is not null then osr.create_date end as Shipped,
case when osr.order_status_cd = 400 and osr.create_date is not null then osr.create_date end as Received,
case when osr.order_status_cd = 500 and osr.create_date is not null then    osr.create_date end as Completed,
from order_status_record osr
inner join msorder mo on mo.order_id = osr.msorder_id

而不是获得如下所示的结果:

OrderID POCreated   Ordered     Shipped      Received    Completed
497822  11/18/2012  NULL          NULL        NULL        NULL
497822  NULL       11/19/2012     NULL        NULL        NULL
497822  NULL        NULL       11/19/2012     NULL        NULL
497822  NULL        NULL          NULL     11/19/2012     NULL
497822  NULL        NULL          NULL        NULL     11/19/2012

我想要这个:

OrderID POCreated   Ordered     Shipped      Received    Completed
497822  11/18/2012  11/19/2012  11/19/2012   11/19/2012  11/19/2012

我是否需要创建虚拟表?我需要if功能吗?为什么Null仍然存在?

非常感谢任何帮助。

谢谢,

安德鲁

3 个答案:

答案 0 :(得分:3)

如果您为每个CASE语句添加聚合函数,然后GROUP BY,则记录将合并为一行:

select mo.order_id OrderID,
  max(case when osr.order_status_cd = 120 and osr.create_date is not null then osr.create_date end) as POCreated,
  max(case when osr.order_status_cd = 220 and osr.create_date is not null then osr.create_date end) as Ordered,
  max(case when osr.order_status_cd = 300 and osr.create_date is not null then osr.create_date end) as Shipped,
  max(case when osr.order_status_cd = 400 and osr.create_date is not null then osr.create_date end) as Received,
  max(case when osr.order_status_cd = 500 and osr.create_date is not null then osr.create_date end) as Completed,
from order_status_record osr
inner join msorder mo 
  on mo.order_id = osr.msorder_id
group by mo.order_id

答案 1 :(得分:2)

使用GROUP BY将订单ID分组到一行,并在case语句中使用MAX以获得正确的行:

select mo.order_id OrderID,
    MAX(case when osr.order_status_cd = 120 and osr.create_date is not null then    osr.create_date end) as POCreated,
    MAX(case when osr.order_status_cd = 220 and osr.create_date is not null then osr.create_date end) as Ordered,
    MAX(case when osr.order_status_cd = 300 and osr.create_date is not null then osr.create_date end) as Shipped,
    MAX(case when osr.order_status_cd = 400 and osr.create_date is not null then osr.create_date end) as Received,
    MAX(case when osr.order_status_cd = 500 and osr.create_date is not null then    osr.create_date end) as Completed,
from order_status_record osr
inner join msorder mo on mo.order_id = osr.msorder_id
GROUP BY order_id

答案 2 :(得分:2)

假设表(msorder_id, order_status_cd)中的UNIQUEorder_status_record,这是一个没有GROUP BY的解决方案:

SELECT 
    mo.order_id         AS OrderID,
    osr120.create_date  AS POCreated,
    osr220.create_date  AS Ordered,
    osr300.create_date  AS Shipped,
    osr400.create_date  AS Received,
    osr500.create_date  AS Completed
FROM 
    msorder AS mo 
  LEFT JOIN 
    order_status_record AS osr120 
      ON  osr120.msorder_id = mo.order_id 
      AND osr120.order_status_cd = 120 
  LEFT JOIN 
    order_status_record AS osr220 
      ON  osr220.msorder_id = mo.order_id 
      AND osr220.order_status_cd = 220 
  LEFT JOIN 
    order_status_record AS osr300 
      ON  osr300.msorder_id = mo.order_id 
      AND osr300.order_status_cd = 300 
  LEFT JOIN 
    order_status_record AS osr400 
      ON  osr400.msorder_id = mo.order_id 
      AND osr400.order_status_cd = 400 
  LEFT JOIN 
    order_status_record AS osr500 
      ON  osr500.msorder_id = mo.order_id 
      AND osr500.order_status_cd = 500 ;