0

我這裏有3個表即:條件語句

person (
    id int PRIMARY KEY 
,fullname text) 

phonenumber (
    id int PRIMARY KEY 
,personid int REFERENCES person(id) 
,phonetypeid REFERENCES phonetype(id) 
,number text) 

phonetype (
id int PRIMARY KEY 
,phonetype text) -- phonetype 'Home', 'Cell', 'Fax', 'Main' etc. 

每個person可以存儲在phonenumber表多個號碼,並有在phonetype表不同PHONETYPE:

| fullname   | number  | phonetype | 
| Erwin Macale  | (671)632-3909 | Home  | 
| Erwin Macale  | (671)632-3909 | Cell  | 
| Erwin Macale  | (671)632-3909 | Main  | 

我只想顯示具有以下條件的每個人的電話號碼:

  • 如果他具有「家庭」電話號碼顯示屏,則只有家庭類型放棄所有其他電話號碼號碼。
  • 如果他沒有「家庭」號碼,則只顯示他的「單元」號碼,然後丟棄他的所有其他(「傳真」,「主」等)號碼。
  • 一個人可以沒有電話號碼。

我創建了包含fullname, number, phonetype命名testable然後從這裏我分開所有PHONETYPE號碼,如一個臨時表:

CREATE TEMP TABLE home AS SELECT * FROM testable WHERE phonetype ILIKE 'home'; 
CREATE TEMP TABLE cell AS SELECT * FROM testable WHERE phonetype ilike 'cell'; 
CREATE TEMP TABLE main AS SELECT * FROM testable WHERE phonetype ilike 'main'; 
CREATE TEMP TABLE fax AS SELECT * FROM testable WHERE phonetype ilike 'fax'; 
CREATE TEMP TABLE work AS SELECT * FROM testable WHERE phonetype ilike 'work'; 
CREATE TEMP TABLE neighbor AS SELECT * FROM testable WHERE phonetype ilike 'neighbor'; 
CREATE TEMP TABLE other AS SELECT * FROM testable WHERE phonetype ilike 'other'; 
CREATE TEMP TABLE unknown AS SELECT * FROM testable WHERE phonetype ilike 'unknown'; 

,然後創建另一組,我認爲滿足上述條件的臨時表:

CREATE TEMP TABLE all_cell AS SELECT * FROM cell EXCEPT SELECT * FROM home; 
CREATE TEMP TABLE all_main AS (SELECT * FROM main) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell); 
CREATE TEMP TABLE all_fax AS (SELECT * FROM fax) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main); 
CREATE TEMP TABLE all_work AS (SELECT * FROM work) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax); 
CREATE TEMP TABLE all_neighbor AS (SELECT * FROM neighbor) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work); 
CREATE TEMP TABLE all_other AS (SELECT * FROM other) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work UNION SELECT * FROM neighbor); 
CREATE TEMP TABLE all_unknown AS (SELECT * FROM unknown) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work UNION SELECT * FROM neighbor UNION SELECT * FROM other); 

最後選擇最後一組臨時表的所有工會:

SELECT fullname, number, phonetype FROM (
    SELECT * FROM home 
    UNION 
    SELECT * FROM all_cell 
    UNION 
    SELECT * FROM all_main 
    UNION 
    SELECT * FROM all_fax 
    UNION 
    SELECT * FROM all_work 
    UNION 
    SELECT * FROM all_neighbor 
    UNION 
    SELECT * FROM all_other 
    UNION 
    SELECT * FROM all_unknown 
) AS t1 
ORDER BY t1.fullname, t1.phonetype; 

步驟是否滿足我的條件? 我仍然從一個人獲得不同的phonetype值。

回答

3

你去了很多麻煩讓一下這個單一的查詢可以給你:

SELECT DISTINCT ON (p.fullname, p.id) 
     p.fullname, n.number, t.phonetype 
FROM phonenumber n 
JOIN person  p ON p.id = n.personid 
JOIN phonetype t ON t.id = n.phonetypeid 
LEFT JOIN (
    VALUES 
    (1, 'home') 
    ,(2, 'cell') 
    ,(3, 'main') 
    ,(4, 'fax') 
    ,(5, 'work') 
    ,(6, 'neighbor') 
    ,(7, 'other') 
    ,(8, 'unknown') 
    ) r(rnk, phonetype) USING (phonetype) 
ORDER BY p.fullname, p.id, r.rnk; 

DISTINCT ON (p.fullname, p.id)因爲fullname可能不是唯一的。無論如何,我使用它來獲得您在單個查詢級別中查找的排序順序。約DISTINCT ON

詳情參加本次相關答案:
Select first row in each GROUP BY group?

我追加排名(r.rnk)信息與VALUES expression,使其與您提交表格的佈局工作。好,不過,你添加到表phonetype永久:

ALTER TABLE phonetype ADD COLUMN rnk int; 

UPDATE phonetype t 
SET rnk = r.rnk 
FROM (
     VALUES 
     (1, 'home') 
     ,(2, 'cell') 
     ,(3, 'main') 
     ,(4, 'fax') 
     ,(5, 'work') 
     ,(6, 'neighbor') 
     ,(7, 'other') 
     ,(8, 'unknown') 
     ) r(rnk, phonetype) 
WHERE r.phonetype = t.phonetype; 

然後將查詢變得更簡單

SELECT DISTINCT ON (p.fullname, p.id) 
     p.fullname, n.number, t.phonetype 
FROM phonenumber n 
JOIN person  p ON p.id = n.personid 
JOIN phonetype t ON t.id = n.phonetypeid 
ORDER BY p.fullname, p.id, t.rnk -- add more columns to break ties (if any)