我有一张这样的表来保存体检结果和发送报告的日期以及结果。实际上发送的日期是基于clinic_visit日期。客户可以有一个或多个报告(日期可能不同)
---------------------------------------
| client_id | date_sent | result |
---------------------------------------
| 1 | 2001 | A |
| 1 | 2002 | B |
| 2 | 2002 | D |
| 3 | 2001 | A |
| 3 | 2003 | C |
| 3 | 2005 | E |
| 4 | 2002 | D |
| 4 | 2004 | E |
| 5 | 2004 | B |
---------------------------------------
我想从以上数据中提取以下报告。
---------------------------------------------------
| client_id | result1 | result2 | resut3 |
---------------------------------------------------
| 1 | A | B | |
| 2 | D | | |
| 3 | A | C | E |
| 4 | D | E | |
| 5 | B | | |
---------------------------------------------------
我正在研究Postgresql。 “交叉表”功能在此处不起作用,因为每个客户端的“date_sent”不一致。
任何人都可以大致了解应该如何查询?
答案 0 :(得分:15)
我建议采用以下方法:
SELECT client_id, array_agg(result) AS results
FROM labresults
GROUP BY client_id;
它的输出格式并不完全相同,但它可以更快,更清晰地为您提供相同的信息。
如果您希望将结果放在不同的列中,您可以随时执行此操作:
SELECT client_id,
results[1] AS result1,
results[2] AS result2,
results[3] AS result3
FROM
(
SELECT client_id, array_agg(result) AS results
FROM labresults
GROUP BY client_id
) AS r
ORDER BY client_id;
虽然这显然会引入一些硬编码的可能结果。
答案 1 :(得分:0)
当我读到“模拟row_number”时,我试图想出另一种方法来做到这一点。
SELECT client_id,
MAX( CASE seq WHEN 1 THEN result ELSE '' END ) AS result1,
MAX( CASE seq WHEN 2 THEN result ELSE '' END ) AS result2,
MAX( CASE seq WHEN 3 THEN result ELSE '' END ) AS result3,
MAX( CASE seq WHEN 4 THEN result ELSE '' END ) AS result4,
MAX( CASE seq WHEN 5 THEN result ELSE '' END ) AS result5
FROM ( SELECT p1.client_id,
p1.result,
( SELECT COUNT(*)
FROM labresults p2
WHERE p2.client_id = p1.client_id
AND p2.result <= p1.result )
FROM labresults p1
) D ( client_id, result, seq )
GROUP BY client_id;
但查询花了10分钟(500,000 ms ++)。 30,000条记录。这太长了..