簡體   English   中英

mySQL SELECT幫助。 IF還是EXISTS?

[英]mySQL SELECT help. IF or EXISTS?

我有這個數據庫結構

* user
user_id
name

* client
client_id
name

* user_client
user_client_id
user_id
client_id

* message
message_id
client_id
description

如果user_client上有條目,則用戶的權限僅限於為其在表上的id列出的特定客戶端。 如果沒有條目,則用戶可以訪問任何客戶端。

如何僅選擇用戶可以閱讀的消息?

我正在嘗試在WHERE子句上執行IF以檢查user_client表上是否有任何條目,但我不知道從那里去哪里。 如果user_client上沒有條目,或者只有user_client表上指定的client_id消息,則需要從任何客戶端選擇所有消息

謝謝您的幫助!

這樣做的一種方法是使用兩個不同的查詢來創建一組用戶可以根據您的需求查看和過濾的消息; 這樣的事情應該有效:

select * from (
    select u.user_id, u.name, c.name client, m.message_id, m.description 
    from user u
    join user_client uc on u.user_id = uc.user_id
    join client c on uc.client_id = c.client_id
    join message m on c.client_id = m.client_id
    union all
    select u.user_id, u.name, c.name client, m.message_id, m.description
    from user u
    cross join client c 
    join message m on c.client_id = m.client_id
    where user_id not in (select user_id from user_client)
) x
where x.user_id = 1;

這里user_client表中的用戶被限制為他們有權訪問的消息集(union中的第一個集),而user_client表中不存在的用戶可以看到所有消息(union中的第二個集)。

示例SQL小提琴

如果我正確理解你的問題,比如

1)管理用戶......他們可以查看所有內容,因為他們在user_client表中沒有記錄。

2)客戶主管......這樣一個人的主要責任是特定客戶(或多個客戶)。 因此,用戶DOES在user_client表中有記錄。 如果是,則僅允許用戶查看他們與之關聯的客戶的記錄。

select
      m.message_id,
      m.client_id,
      m.description,
      c.name as clientName
   from
      ( select count(*) as HasClients
           from user_client
           where user_id = TheUserYouWant ) ClientCheck,
      message m
         left join user_client uc
            on m.client_id = uc.client_id
           AND uc.user_id = TheUserYouWant
         join client c
            on m.client_id = c.client_id
   where
         ClientCheck.HasClients = 0
      OR NOT uc.user_id IS NULL

該查詢查看user_client表TWICE。 第一次是獲取給定用戶存在的那些記錄的計數,而不管與哪個客戶關聯。 查詢將始終返回1行,它將為0(沒有此類記錄)或大於1(無論它們與多少相關聯)。

第二個實例是對user_client表的LEFT-JOIN,JUST IN CASE該人被限制為僅查看他們自己的客戶端消息。

WHERE子句現在進來並說...如果客戶端的基礎數量為零,那么可以給我所有消息。 如果有任何其他值,那么user_client表中的用戶ID(左邊連接到你想要的CLIENT和USER上的消息)必須存在(通過NOT user_id列的NULL值)。

現在,您可能不希望查詢每條消息,因為它可能會隨着數據庫的增長而變得非常大,但您可以在WHERE子句中添加任何其他條件,例如您感興趣的日期限制和/或客戶端。

我建議做兩個不同的查詢:一個用於超級用戶 ,另一個用於受限用戶。 然后你可以用UNION加入這兩個結果。

    SELECT M.message_id,
           M.client_id,
           M.description
      FROM message M
INNER JOIN user_client UC ON (UC.client_id = M.client_id)
INNER JOIN user U ON (UC.user_id = U.id)
     WHERE U.id = :user_id

     UNION

    SELECT M.message_id,
           M.client_id,
           M.description
      FROM message M
     WHERE NOT EXISTS ( 
               SELECT *
                 FROM user_client
                WHERE user_id = :user_id
           )

您可以使用其他查詢獲得相同的結果,但恕我直言這一個更清晰,更易於維護。

編輯:如果要確保用戶存在,則應將第二個查詢與用戶表一起加入。

    SELECT M.message_id,
           M.client_id,
           M.description
      FROM message M
      JOIN user U
     WHERE U.id = :user_id
       AND NOT EXISTS ( 
               SELECT *
                 FROM user_client
                WHERE user_id = :user_id
           )

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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