在多行

时间:2017-12-14 23:32:17

标签: sql presto

我有一张表格

 id_customer__ |        status         |     time_stmpd_at     | idx
---------------+-----------------------+-----------------------+-----
        112220 | enabled____________at | 2017-12-13 16:12:42.0 |   1
        112220 | sale_locked_at__      | 2017-12-13 14:52:43.0 |   2
        112220 | qual_sale_at          | 2017-12-06 12:22:50.0 |   3
        112220 | quality_control___at  | 2017-11-28 18:22:02.0 |   4
        112220 | returned__at          | 2017-10-12 23:02:41.0 |   5

我希望status idx = 2和time_stmpd_at,其中idx = 1.并且能够为所有客户ID执行此操作。

我试图将条件放入select语句中,如下所示:

select
  id_customer__,
  if(idx=2, status, NULL) as previous_status,
  if(idx=1, time_stmpd_at, NULL) as time_stmpd_at
from htable

但这让我失望

 id_customer__ | previous_status  |      time_stmpd_at
---------------+------------------+-----------------------
        119650 | NULL             | 2017-12-13 16:12:42.0
        119650 | sale_locked_at__ | NULL
        119650 | NULL             | NULL
        119650 | NULL             | NULL
        119650 | NULL             | NULL

接下来,我必须将该字段合并为一行。但我觉得必须有更好的方法。有关整体方法的任何建议吗?

3 个答案:

答案 0 :(得分:3)

您可以使用条件聚合执行此操作。

select
  id_customer__,
  max(case when idx=2 then status end) as previous_status,
  max(case when idx=1 then time_stmpd_at end) as time_stmpd_at
from htable
group by id_customer__

答案 1 :(得分:1)

您可以使用MAX并将表格限制为只有您想要的索引(您不必这样做但是为什么还要计算不相关的行):

SELECT id_customer__, 
    MAX(CASE WHEN idx=1 THEN time_stmpd_at ELSE NULL END) time_stmpd_at,
    MAX(CASE WHEN idx=2 THEN status ELSE NULL END) status
FROM htable 
WHERE idx IN (1,2)
GROUP BY id_customer__

或者您可以单独提取这些索引并在id_customer__

上加入它们
SELECT h1.id_customer__, h1.time_stmpd_at , h2.status 
FROM
(SELECT * FROM htable WHERE idx=1) h1 INNER JOIN
(SELECT * FROM htable WHERE idx=2) h2 ON h1.id_customer__ = h2.id_customer__

答案 2 :(得分:0)

(基于@VamsiPrabhala的回答,但改为使用arbitrary聚合)

我建议使用arbitrary聚合(而不是max),因为它更能传达意义:

select id_customer,
  arbitrary(status) filter(where idx=2) as previous_status,
  arbitrary(time_stmpd_at) filter(where idx=1) as time_stmpd_at
from htable
group by id_customer

使用arbitrary有两个原因:

  1. arbitrary表示您没有进行任何max聚合(如果以后有人会阅读此查询,这很好)
  2. 没有任何聚合会拒绝多个值。如果有,我建议使用arbitrary