簡體   English   中英

PostgreSQL查詢中的條件語句

[英]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.

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