2015-02-23 82 views
0

我有這個DB結構mySQL SELECT幫助。 IF還是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,則需要選擇來自任何客戶端的所有消息。表

感謝您的幫助!

+0

您能否顯示您正在嘗試修復的查詢? – Alex 2015-02-23 17:37:08

+0

你在這裏?你會回答我的問題嗎?並顯示預期的結果? – Alex 2015-02-23 18:23:57

+0

嗨,亞歷克斯!剛剛看到你的消息。我沒有完成查詢,因爲我意識到正在走錯方向,我錯過了一些東西。但是,這是我有什麼: 選擇 \t \t \t message.message_id, \t \t \t message.description \t \t FROM \t \t \t消息 \t \t WHERE \t \t \t discussionMessage.insertWhen> = DATE_SUB(NOW( ),INTERVAL 5 MINUTE) \t \t \t AND \t \t \t IF((SELECT COUNT(1)FROM user_client WHERE USER_ID = user.user_id)> = 1 \t \t \t \t \t \t message.clientId IN( \t \t \t \t SELECT \t \t \t \t \t CLIENT_ID \t \t \t \t FROM \t \t \t \t \t user_client \t \t \t \t WHERE \t \t \t \t \t user_client.userId = {} USERIDHERE \t \t \t),) – Kitara 2015-02-23 18:37:24

回答

0

我會建議做兩個不同的查詢:一個用於超級用戶另一個用於限制用戶。然後你可以用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 
      ) 
+0

霍爾迪嗨!我能夠使用您的查詢使其在我身邊工作!謝謝,我一直在完成,並會在我做所有測試時立即被接受爲答案。 – Kitara 2015-02-23 18:39:43

+0

謝謝。請記住,如果你傳遞一個不存在的:user_id,它將返回所有的消息。您可以在調用查詢之前確保用戶存在,或者修改聯合的第二部分以檢查用戶是否存在。 – 2015-02-23 18:49:45

+0

Hi @ jordi-llull它的工作原理,我剛剛看到你發送的關於返回所有消息的消息,如果用戶不存在,我應該使用mysql查詢來驗證它,如果返回的行數大於零,它會調用消息查詢或您的消息意味着什麼,是否可以添加到查詢中? – Kitara 2015-02-23 19:33:48

0

這樣做的一種方式可能是使用兩個不同的查詢來創建一組用戶可以根據需要查看和過濾的消息;這樣的事情應該工作:

存在於user_client表
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表不存在時,查看所有消息(聯合中的第二組)。

Sample SQL Fiddle

0

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

1)管理用戶......他們可以看看一切,因爲他們將不得不在user_client表中沒有記錄。

2)客戶主管......這樣的主要責任人是特定的客戶(或多個客戶)。因此,用戶在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表,只是在情況下,人員被限制爲僅查看他們自己的客戶端消息。

WHERE子句現在進入並說...如果客戶端的基礎計數爲零,那麼可以給我所有的消息。如果有任何其他值,則user_client表中的用戶標識(作爲客戶和用戶所需的消息的左連接)必須爲EXIST(通過非user_id列的NULL值)。

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