2

我有一个问题,我的 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 函数吗?为什么 Nulls 仍然存在?

任何帮助将非常感激。

谢谢,

安德鲁

4

3 回答 3

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
于 2012-11-23T17:41:17.957 回答
2

用于GROUP BY将订单 ID 分组为一行,并MAX在 case 语句中获取正确的行:

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
于 2012-11-23T17:41:57.063 回答
2

假设在表中,这是一个没有的解决(msorder_id, order_status_cd)方案:UNIQUEorder_status_recordGROUP 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 ;
于 2012-11-23T18:35:48.187 回答