Postgresql

檢查實體是否與關係中的 id 匹配,它可以顯示在兩列中的任何一列中

  • April 13, 2021

問題

我正在嘗試為一個網站(使用 PostgreSQL 數據庫)創建一個頁面,該頁面允許組的所有者從他們的朋友列表中添加新成員。

鑑於它owner_id的s,我只需要從與所有者都是朋友的使用者中檢索 s,而不是在組中。Group``group_id``user_id

被查詢的關係

我需要使用以下關係

  • UserFriend:儲存兩個user_ids 以將這兩個使用者從User彼此的關係中連接為朋友。
  • UserGroup:儲存 auser_id並將關係group_id連接到Group關係中的成員User

這兩種關係描述如下:

使用者朋友

 Column   |  Type   | Collation | Nullable | Default 
-----------+---------+-----------+----------+---------
user_id_a | integer |           | not null | 
user_id_b | integer |           | not null | 

使用者組

 Column  |  Type   | Collation | Nullable | Default 
----------+---------+-----------+----------+---------
user_id  | integer |           | not null | 
group_id | integer |           | not null | 

到目前為止我對範例數據的嘗試

例如,給定下面的數據,我想查找與使用者 3 為朋友的所有使用者,而不是在組 3 中的所有使用者。

SELECT user_id_a, user_id_b FROM UserGroup UG, UserFriend UF 
   WHERE (UF.user_id_a = 3 AND UF.user_id_b != UG.user_id)
      OR (UF.user_id_b = 3 AND UF.user_id_a != UG.user_id)
      AND UG.group_id = 3 GROUP BY user_id_a, user_id_b;

預期結果

user_id_a | user_id_b 
-----------+-----------
        1 |         3

如果它可以顯示類似的東西就更好了

possible_members 
------------------
               3

實際結果

user_id_a | user_id_b 
-----------+-----------
        1 |         3
        3 |         2
        3 |         4

範例數據

使用者朋友

user_id_a | user_id_b 
-----------+-----------
        1 |         2
        1 |         3
        1 |         4
        3 |         4
        3 |         2

使用者組

user_id | group_id 
---------+----------
      1 |        1
      2 |        1
      3 |        1
      4 |        1
      1 |        2
      2 |        3
      3 |        3
      4 |        3

分析

我相當確定這個問題與我處理我試圖匹配的事實的方式有關,user_id我試圖匹配的可能是在任一列中UserFriend,但我不確定如何解決它。我也試過使用JOINs 沒有任何運氣。

使用集合操作。如果使用者是 42,組是 1001,那將是

(SELECT user_id_a FROM userfriend
WHERE user_id_b = 42
   UNION
SELECT user_id_b FROM userfriend
WHERE user_id_a = 42
)
  EXCEPT
SELECT user_id FROM usergroup
WHERE group_id = 1001;

UNION創建一個結果集,該結果集是兩個查詢結果的並集並刪除重複的行。EXCEPT從左側返回所有出現在右側的結果行。

引用自:https://dba.stackexchange.com/questions/289702