2017-05-09 37 views
0

輸入值加入我有三個表:條件與postgreslq功能

create table id_table (
    id integer 
); 

insert into id_table values (1),(2),(3); 

create table alphabet_table (
    id integer, 
    letter text 
); 

insert into alphabet_table values (1,'a'),(2,'b'),(3,'c'); 

create table greek_table (
    id integer, 
    letter text 
); 

insert into greek_table values (1,'alpha'),(2,'beta'); 

我喜歡創建加入id_table有兩種alphabet_table或greek_table上ID的功能。表的選擇取決於函數中指定的輸入值。我寫道:

CREATE OR REPLACE FUNCTION choose_letters(letter_type text) 
    RETURNS table (id integer,letter text) AS $$ 
BEGIN 
    RETURN QUERY 
    select t1.id, 
     case when letter_type = 'alphabet' then t2.letter else t3.letter end as letter 
    from id_table t1, 
     alphabet_table t2 , 
     greek_table t3 
    where t1.id = t2.id and t1.id = t3.id; 

END; 
$$LANGUAGE plpgsql; 

我跑select choose_letter('alphabet')。這個代碼的問題是,當id_table與alphabet_table聯合時,它不會接收id,No 3.似乎內部聯接對於alphabet_table和greek_table都已完成(所以它只會提取常見的id,1和2)。爲了避免這個問題,我寫道:

CREATE OR REPLACE FUNCTION choose_letters(letter_type text) 
    RETURNS table (id integer, letter text) AS $$ 
BEGIN 
    RETURN QUERY 
    select t1.id, 
     case when letter_type = 'alphabet' then t2.letter else t3.letter end as letter 
    from id_table t1 
    left join alphabet_table t2 on t1.id=t2.id 
    left join greek_table t3 on t1.id=t3.id 
    where t2.letter is not null or t3.letter is not null; 

END; 
$$LANGUAGE plpgsql; 

現在它拿起id_table和alphabet_table連接時的所有3個ID。但是,當我跑select choose_letter('greek')。 ID號。 3在字母列中出現空值,儘管我在where子句中指定了t3.letter is not null

我在找的是當我運行select choose_letters('alphabet')時,輸出需要是(1,'a'),(2,'b'),(3,'c')。 select choose_letters('greek')應該產生(1,'alpha'),(2,'beta)。沒有缺失的值也不爲空。我怎樣才能做到這一點?

回答

1

學習使用正確的,明確的JOIN語法。簡單的規則:從不FROM子句中使用逗號。

你可以做你想要LEFT JOIN和其他一些邏輯是什麼:

select i.id, 
     coalesce(a.letter, g.letter) as letter 
from id_table i left join 
    alphabet_table a 
    on i.id = a.id and letter_type = 'alphabet' left join 
    greek_table g 
    on i.id = g.id and letter_type <> 'alphabet' 
where a.id is not null or g.id is not null; 

使用letter_type需求是在on條款的條件。否則,alphabet_table將始終有匹配。

+0

這幾乎是相同的問題第二個代碼。當'letter_type <>'alphabet''時,它在ID號3 – midtownguru

+0

@midtownguru中顯示空值。 。 。有一個重要的區別。但是,謝謝你指出我已經排除了where子句。 –

+0

我得到了'left join'邏輯。你可以在問題中看到我的最後一個代碼。有趣的是,對我而言,'coalesce'和'letter_type'正在解決這個問題。 – midtownguru

0

第一個問題是你的表格或者結構不正確,你會創建一個像char_table(id int,letter text,type text)類型的單個表格來指定它是字母表還是希臘字母。

另一種方案是,你可以寫兩個SQL查詢之一,如果條件另一個是在其他部分