簡體   English   中英

SQL合並多行

[英]SQL Consolidating Multiple rows

我正在簡化問題,但是這里的概念應該是相同的...

假設我們有一個具有字段IDATTRIB的表FOO ,以及一個具有字段IDA_MATCHING_IDSTATUS的表BAR 這些表如下所示:

表FOO:

ID    -     ATTRIB
=====
1001  -     ATR_A
1002  -     ATR_B
1003  -     ATR_A
1004  -     ATR_B
1005  -     ATR_B

etc.

表欄:

ID    -     FOO_MATCHING_ID   -     STATUS
=====
9901  -     1001              -     STAT_A
9902  -     1001              -     STAT_A
9903  -     1001              -     STAT_B
9904  -     1002              -     STAT_C
9905  -     1002              -     STAT_B
9906  -     1002              -     STAT_B
9907  -     1003              -     STAT_A

etc.

FOOBAR一對多的關系。

我想對具有計算/相關字段[HAS_STAT_A]的兩個表運行查詢:

預期查詢結果:

FOO_ID      -     HAS_STAT_A
=====
1001        -     TRUE
1002        -     FALSE
1003        -     TRUE

我該怎么做?

SELECT FOO.ID AS FOO_ID, [FILL THIS IN] AS HAS_STAT_A 
FROM FOO 
JOIN BAR ON FOO.ID = BAR.FOO_MATCHING_ID;

我曾想過使用CASE ,但不知道如何在多個記錄中使用它。 我還考慮添加一些額外的子查詢,但也不確定如何安排這些子查詢。

這是相似的 ,但不是我想要實現的。 這導致我遇到以下類似問題,但是出現了GROUP BY錯誤。 當我添加GROUP BY ,出現MISSING KEYWORD錯誤。

SELECT FOO.ID AS FOO_ID, 
    INSTR (LISTAGG (BAR.STATUS, ',') WITHIN GROUP (ORDER BY BAR.STATUS), 'STAT_A') AS HAS_STAT_A 
FROM FOO 
JOIN BAR ON FOO.ID = BAR.FOO_MATCHING_ID; 
select  foo.id as foo_id
,       case 
        when max(case when lower(trim(bar.status)) = 'stat_a' then 1 end) = 1 then 'true' 
        else 'false' 
        end as has_stat_a 
from    foo 
join    bar
on      foo.id = bar.foo_matching_id
group by
        foo.id

這是一種方法

SELECT 
    FOO.ID AS FOO_ID, 
    SUM(CASE WHEN BAR.[STATUS]='STAT_A' THEN 1 ELSE 0 END) AS HAS_STAT_A
FROM FOO 
    INNER JOIN BAR ON FOO.ID = BAR.FOO_MATCHING_ID
GROUP BY
    FOO.ID

您也可以使用“ having”關鍵字來過濾掉has_stat_a為0的行。

SELECT 
    FOO.ID AS FOO_ID, 
    SUM(CASE WHEN BAR.[STATUS]='STAT_A' THEN 1 ELSE 0 END) AS HAS_STAT_A
FROM FOO 
    INNER JOIN BAR ON FOO.ID = BAR.FOO_MATCHING_ID
GROUP BY 
    FOO.ID
HAVING
    SUM(CASE WHEN BAR.[STATUS]='STAT_A' THEN 1 ELSE 0 END) = 1

如果foo中可能存在在bar沒有匹配行的行,那么您可以嘗試這樣的操作:

SELECT
    foo.id AS foo_id,
    NVL
    (
        (
            SELECT
                'TRUE'
            FROM
                bar
            WHERE
                bar.foo_matching_id = foo.id
                AND
                bar.STATUS = 'STAT_A'
                AND
                ROWNUM <= 1
        ),
        'FALSE'
    )
FROM
    foo

可能存在更有效的方式來重寫此查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM