[英]Conditional Statement in PostgreSQL Query
我這里有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
表中存儲多個號碼,並在phonenumber
表中擁有不同的phonenumber
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;
滿足我的條件的步驟正確嗎? 我仍然從一個人那里獲得不同的電話類型值。
要獲得此單個查詢可以為您提供的服務,您很麻煩:
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
詳細信息:
在每個GROUP BY組中選擇第一行?
我在排名( r.rnk
)信息后附加了VALUES
表達式,以使其與您提供的表布局一起使用。 不過,更好的是,將表的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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.