使用“条件聚合”是处理此类需求的传统且仍然有效的方法:
SQL小提琴
PostgreSQL 9.6 架构设置:
CREATE TABLE AUDIT_TABLE
(USER_ENTL_ID int, USER_STATUS varchar(2), CREATED_DATE timestamp)
;
INSERT INTO AUDIT_TABLE
(USER_ENTL_ID, USER_STATUS, CREATED_DATE)
VALUES
(1, 'S', '2017-10-20 00:00:00'),
(1, 'C', '2017-10-21 00:00:00'),
(1, 'W', '2017-10-22 00:00:00'),
(1, 'SP', '2017-10-23 00:00:00'),
(2, 'S', '2017-10-24 00:00:00'),
(2, 'C', '2017-10-25 00:00:00')
;
查询 1:
注意,在此使用 MIN 或 MAX 可能很重要,具体取决于您的数据,但我每个输出位置的数据中只有一个值,然后可以使用任一函数。
SELECT
USER_ENTL_ID
, MAX(CASE WHEN USER_STATUS = 'S' THEN USER_STATUS END) s_status
, MIN(CASE WHEN USER_STATUS = 'S' THEN CREATED_DATE END) s_created
, MAX(CASE WHEN USER_STATUS = 'C' THEN USER_STATUS END) c_status
, MIN(CASE WHEN USER_STATUS = 'C' THEN CREATED_DATE END) c_created
, MAX(CASE WHEN USER_STATUS = 'W' THEN USER_STATUS END) w_status
, MIN(CASE WHEN USER_STATUS = 'W' THEN CREATED_DATE END) w_created
, MAX(CASE WHEN USER_STATUS = 'SP' THEN USER_STATUS END) sp_status
, MIN(CASE WHEN USER_STATUS = 'SP' THEN CREATED_DATE END) sp_created
FROM AUDIT_TABLE
GROUP BY
USER_ENTL_ID
结果:
| user_entl_id | s_status | s_created | c_status | c_created | w_status | w_created | sp_status | sp_created |
|--------------|----------|----------------------|----------|----------------------|----------|----------------------|-----------|----------------------|
| 1 | S | 2017-10-20T00:00:00Z | C | 2017-10-21T00:00:00Z | W | 2017-10-22T00:00:00Z | SP | 2017-10-23T00:00:00Z |
| 2 | S | 2017-10-24T00:00:00Z | C | 2017-10-25T00:00:00Z | (null) | (null) | (null) | (null) |
添加
进一步解释:如果您删除 MIN 或 MAX 函数并删除 group by,这就是您得到的:
+--------------+----------+----------------------+----------+----------------------+----------+----------------------+-----------+----------------------+
| user_entl_id | s_status | s_created | c_status | c_created | w_status | w_created | sp_status | sp_created |
+--------------+----------+----------------------+----------+----------------------+----------+----------------------+-----------+----------------------+
| 1 | S | 2017-10-20T00:00:00Z | (null) | (null) | (null) | (null) | (null) | (null) |
| 1 | (null) | (null) | C | 2017-10-21T00:00:00Z | (null) | (null) | (null) | (null) |
| 1 | (null) | (null) | (null) | (null) | W | 2017-10-22T00:00:00Z | (null) | (null) |
| 1 | (null) | (null) | (null) | (null) | (null) | (null) | SP | 2017-10-23T00:00:00Z |
| 2 | S | 2017-10-24T00:00:00Z | (null) | (null) | (null) | (null) | (null) | (null) |
| 2 | (null) | (null) | C | 2017-10-25T00:00:00Z | (null) | (null) | (null) | (null) |
+--------------+----------+----------------------+----------+----------------------+----------+----------------------+-----------+----------------------+
如果您研究一下,您会发现对于我们关心的数据,每行只有一个值(对于每个 USER_ENTL_ID),但它们分布在几行中。所以 MIN/MAX 函数和 GROUP BY “扁平化”了结果,所以我们最终得到了想要的结果。量子点