如何像ROW,ARRAY那样拆分复合列?

时间:2010-08-02 12:11:57

标签: sql postgresql

我遇到了与此停止线程相同的问题。

http://www.mail-archive.com/pgsql-sql@postgresql.org/msg28070.html

QUERY-1

SELECT 
r.id,
(
        SELECT 
        rl.reminder_header,
        rl.reminder_footer
        FROM reminder_levels AS rl
        WHERE rl.lookup =
        (
                SELECT MAX(reminder_level_lookup) 
                FROM reminders
                WHERE customer_id = r.customer_id
        )
)
FROM reminders AS r

Postgresql回复说:
错误:子查询必须只返回一列

QUERY-2

SELECT 
r.id,
(
        SELECT 
        rl.reminder_header
        FROM reminder_levels AS rl
        WHERE rl.lookup =
        (
                SELECT MAX(reminder_level_lookup) 
                FROM reminders
                WHERE customer_id = r.customer_id
        )
) AS reminder_header,
(
        SELECT 
        rl.reminder_footer
        FROM reminder_levels AS rl
        WHERE rl.lookup =
        (
                SELECT MAX(reminder_level_lookup) 
                FROM reminders
                WHERE customer_id = r.customer_id
        )
) AS reminder_footer
FROM reminders AS r

id  |  reminder_header  |  reminder_footer
----+-------------------+--------------------
1   |  hogehoge         |  fugafuga

...有效,但运行两次相同的子选择块 这会导致性能下降 (但是,这个结果表就是我想要的。)

QUERY-3

SELECT 
r.id,
(
        SELECT 
        ROW(rl.reminder_header, rl.reminder_header)
        FROM reminder_levels AS rl
        WHERE rl.lookup =
        (
                SELECT MAX(reminder_level_lookup) 
                FROM reminders
                WHERE customer_id = r.customer_id
        )
) AS rec
FROM reminders AS r

id  |  rec
----+----------------------
1   |  (hogehoge, fugafuga)

......哪个有效,但是'rec'列是复合的。

如何将此'rec'拆分为reminder_header和reminder_footer, 像Query-2。

有一些程序或tequnique? 或其他解决方案?

感谢。

2 个答案:

答案 0 :(得分:1)

要从子查询中选择多个列,通常使用连接。现在我不确定你的表格究竟是如何相关的,但这样的事情将是一个良好的开端:

SELECT  r.id
,       rl.reminder_header
,       rl.reminder_footer
FROM    reminders r
JOIN    reminder_levels AS rl
ON      rl.customer_id = r.customer_id
WHERE   rl.lookup =
        (
        SELECT  MAX(reminder_level_lookup) 
        FROM    reminders r2
        WHERE   r2.customer_id = r.customer_id
        )

答案 1 :(得分:1)

你可以这样做:

with query as ( 
SELECT 
r.id,
(
        SELECT 
        r1::reminder_levels
        FROM reminder_levels AS rl
        WHERE rl.lookup =
        (
                SELECT MAX(reminder_level_lookup) 
                FROM reminders
                WHERE customer_id = r.customer_id
        )
) AS rec
FROM reminders AS r)
select id,
       (rec::reminder_levels).reminder_header,
       (rec::reminder_levels).reminder_footer
from query