2017-02-16 60 views
0

我有2個表格「記錄」和「字符」。有1 - > N的關係 我需要做一個選擇,使用子查詢/連接,其中連接列上顯示的值是一個固定的字符串,如「多個字符」或內容Char.char_val有條件的列值,請選擇

讓我來舉例說明:

記錄:

 R_ID | Name  Char: C_ID | R_ID | Char_Val 
     1 A     1  3  c1 
     2 B     2  1  c2 
     3 C     3  1  c3 
           4  2  c3 

預期結果:

 R_ID | Name | Char_Val 
     1 A  Multiple Records 
     2 B    c3 
     3 C    c1 

我想我的查詢會是這樣的:

Select r.R_ID, r.Name, (conditional select) Char_Val 
From Records r, Char c 
where r.R_ID = c.R_ID 

對(有條件選擇)的建議?

+1

您可以用'listagg'用於此目的 – Rahul

+1

你不應該使用20世紀80年代聯接了。改用適當的ANSI連接('從記錄r連接字符r.R_ID = c.R_ID')。 –

回答

1

集團通過R_ID。無論是MIN = MAX或者你想「多個記錄」:

select r_id, r.name, c.char_vals 
from 
(
    select 
    r_id, 
    case when min(char_val) = max(char_val) then min(char_val) else 'Multiple Records' end 
     as char_vals 
    from char 
    group by r_id 
) c 
join records r using(r_id) 
order by r_id; 
+0

當場!最乾淨/優雅的答案。注意將來的讀者:我做了一個**正確的連接**,而不是顯示與沒有關聯的Char_Val的記錄的R_ID和名稱。感謝您的幫助! – Drew

1

下面的查詢給出結果(與Char_val用逗號分隔)你的預期:

Select r.R_ID, r.Name, listagg(c.char_val,',') WITHIN GROUP(ORDER BY c.char_val) AS Char_Val 
From Records r, Char c 
where r.R_ID = c.R_ID 
GROUP BY r.R_ID, r.Name 
+0

這不是OP期望的輸出;他們說他們想要一個像「多個字符」這樣的固定字符串,儘管他們在預期結果中顯示了不同的固定字符串「多個記錄」。它沒有說他們想要來自多行的實際值? –

2

您可以使用一個case語句和聚合得到一個固定的字符串:

case when count(c.c_id) > 1 then 'Multiple Records' else max(c.char_val) end 

和您需要按r_idname進行分組:

select r.r_id, r.name, 
    case when count(c.c_id) > 1 then 'Multiple Records' 
    else max(c.char_val) end as char_val 
from records r 
join char c on r.r_id = c.r_id 
group by r.r_id, r.name 
order by r.r_id;  

我也切換到使用ANSI連接,而不是舊的語​​法(如@Thorsten建議)。

這是一個使用CTE來生成你的數據,讓他們稍微不同的名稱,因爲char是保留字演示:

with t_records (r_id, name) as (
    select 1, 'A' from dual 
    union all select 2, 'B' from dual 
    union all select 3, 'C' from dual 
), 
t_char (c_id, r_id, char_val) as (
    select 1, 3, 'c1' from dual 
    union all select 2, 1, 'c2' from dual 
    union all select 3, 1, 'c3' from dual 
    union all select 4, 2, 'c3' from dual 
) 
select r.r_id, r.name, 
    case when count(c.c_id) > 1 then 'Multiple Records' 
    else max(c.char_val) end as char_val 
from t_records r 
join t_char c on r.r_id = c.r_id 
group by r.r_id, r.name 
order by r.r_id;  

     R_ID N CHAR_VAL   
---------- - ---------------- 
     1 A Multiple Records 
     2 B c3    
     3 C c1