显示基于重复行和空值的特定输出数据[postgresql]

时间:2013-04-24 20:04:21

标签: sql postgresql

我正在使用以下SQL(带有两个类似查询的联合):

SELECT
    distinct a.source,
    a.p_id,
    a.name,
    b.prod_count,
    b.prod_amt,
    'Def' as prod_type
FROM
    dwh.attribution_product_count a
        LEFT OUTER JOIN
        (
SELECT
    distinct source,
    p_id,
    name,
    sum(acct_count) as prod_count,
    sum(acct_amt) as prod_amt
FROM
    dwh.prod_count
WHERE
    month = 3 AND
    default_banner_flag = 0 AND
    loan_flag = 3
GROUP BY
    source,
    name,
    p_id ) as b
        ON
        a.p_id = b.p_id
UNION
SELECT
    distinct a.source,
    a.p_id,
    a.name,
    b.prod_count,
    b.prod_amt,
    'Other' as prod_type
FROM
    dwh.attribution_product_count a
        LEFT OUTER JOIN
        (
SELECT
    distinct source,
    p_id,
    name,
    sum(acct_count) as prod_count,
    sum(acct_amt) as prod_amt
FROM
    dwh.prod_count
WHERE
    month = 3 AND
    default_banner_flag = 1 AND
    loan_flag = 3
GROUP BY
    source,
    name,
    p_id
ORDER BY
    name ) as b
        ON
        a.p_id = b.p_id

我得到的输出看起来像这样:

enter image description here 基本上,因为FakeName#2有一行显示实际数字(非空),我只想要FakeName#2出现。这意味着我还想要FakeName#2的空行。但是,由于FakeName#1和#3有2个空行,我不需要它们显示。什么类型的SQL命令(或编辑我的查询)可以实现这一目标?

1 个答案:

答案 0 :(得分:1)

首先,如果我正确阅读了您的查询,您可以使用UNIONCASE来消除对IN的需求。你还有一些虚假的DISTINCT(因为你无论如何都在使用GROUP BY)。这给了:

SELECT DISTINCT
    a.source,
    a.p_id,
    a.name,
    b.prod_count,
    b.prod_amt,
    Case When default_banner_flag = 0 Then 'Def' Else 'Other' End as prod_type
FROM
    dwh.attribution_product_count a
LEFT OUTER JOIN
    (
    SELECT
        source,
        p_id,
        name,
        default_banner_flag,
        sum(acct_count) as prod_count,
        sum(acct_amt) as prod_amt
    FROM
        dwh.prod_count
    WHERE
        month = 3 AND
        default_banner_flag in (0, 1) AND
        loan_flag = 3
    GROUP BY
        source,
        name,
        p_id,
        default_banner_flag
) as b
ON
a.p_id = b.p_id

但是,您真正想要的是有关p_iddwh.prod_count中至少有一行的信息,因此我认为您可以更改整个查询以将其用作子选项:

SELECT
    a.source,
    a.p_id,
    a.name,
    sum(acct_count) as prod_count,
    sum(acct_amt) as prod_amt,
    Case When default_banner_flag = 0 Then 'Def' Else 'Other' End as prod_type
FROM
    dwh.attribution_product_count a
LEFT OUTER JOIN
    dwh.prod_count b
    On a.p_id = b.p_id
INNER JOIN
    (
    SELECT DISTINCT
        p_id
    FROM
        dwh.prod_count
    WHERE
        month = 3 AND
        default_banner_flag in (0, 1) AND
        loan_flag = 3
    ) as c
    ON a.p_id = c.p_id
WHERE
    month = 3 AND
    default_banner_flag in (0, 1) AND
    loan_flag = 3

(您也可以将其重写为WHERE p_id IN ( sub-select )或稍微有点WHERE EXISTS ( ... ),但这似乎是最容易展示的版本。)

请注意,我实际上没有测试任何这些查询,但我认为它们在逻辑上是合理的。