2010-11-16 34 views
0

我無法搞清楚查詢。我有三張桌子選擇哪裏會員只屬於一個客戶

messages 
--------------- 
message_id 
phone_num 
body 
received_time 

subscribers 
--------------- 
phone_num 
keyword_id 

keywords 
--------------- 
keyword_id 
client_id 

訂閱者可以屬於不同客戶端的很多關鍵字。我想查找屬於一個特定客戶但不是其他客戶的最近消息,因此只有一個客戶總數。

例如尋找從用戶誰只屬於客戶端1最近的消息,與數據:

message_id  phone_num body   received_time 
1    111   hi   123456 
2    222   test   123489 
3    333   msg   213445 

phone_num keyword_id 
111   1 
111   2 
222   3 
333   4 
333   5 

keyword_id  client_id 
1    1 
2    1 
3    1 
4    1 
5    4 

我會想:

message_id phone_num body received_time 
2   222   test 123489 
1   111   hi  123456 

由於號碼111和222只屬於一個客戶端

有意義嗎?我無法弄清楚。謝謝

+0

我看到SUBSCRIBERS和KEYWORDS之間的關係,但MESSAGES和其他兩個表之間沒有關係。 – 2010-11-16 05:48:08

+0

明顯是phone_num列。 – cdhowie 2010-11-16 05:54:53

+0

是的,對不起,它的電話號碼 – bones 2010-11-16 15:55:36

回答

0

您的任何查詢都不適合我,他們凍結了服務器。不知道爲什麼,可能是糟糕的索引。但我想出了一個查詢運行得非常快

SELECT DISTINCT m.message_id AS unique_id, m.phone_num, m.body, m.system_time 
FROM messages m 
JOIN subscribers s ON m.phone_num = s.phone_num 
JOIN keywords k ON s.keyword_id = k.keyword_id 
WHERE m.phone_num NOT 
    IN (
     SELECT s.phone_num 
     FROM subscribers s, keywords k 
     WHERE k.client_id != 'XXXX' 
     AND k.keyword_id = s.keyword_id 
) 
ORDER BY m.system_time DESC 

感謝您的幫助,如果任何人都可以改善我的查詢,請做!

0

在具有相同模擬數據的數據庫中,此查詢適用於我。它可能不會很快,但它會完成工作。

SELECT m.* FROM messages m 

WHERE m.phone_num IN (
    SELECT DISTINCT s.phone_num FROM subscribers s, keywords k 

    WHERE s.keyword_id = k.keyword_id 
     AND k.client_id = ??? 
     AND NOT EXISTS (
      SELECT ki.client_id FROM keywords ki, subscribers si 

      WHERE ki.keyword_id = si.keyword_id 
      AND si.phone_num = s.phone_num 
      AND ki.client_id <> k.client_id 
     ) 
) 
+0

謝謝,但我怎麼會得到的消息,以特定的客戶?例如,我希望來自僅屬於客戶端23的訂戶的所有消息到客戶端23. – bones 2010-11-16 15:49:46

+0

我已將該子句添加到查詢中。只要用你感興趣的客戶ID替換???。 – cdhowie 2010-11-16 19:20:37

0

我建造這個複雜的查詢:

SELECT 
    m.message_id, m.phone_num, m.body, m.received_time 

FROM 
    messages m 

WHERE m.phone_num IN (
    SELECT 
    phone_num 
    FROM 
    subscribers s, 
    keywords k 
    WHERE 
    s.keyword_id = k.keyword_id AND 
    k.client_id = 1 AND 
    s.phone_num IN (
     SELECT 
     s.phone_num 
     FROM 
     subscribers s, keywords k 
     WHERE 
     s.keyword_id = k.keyword_id 
     GROUP BY s.phone_num 
     HAVING COUNT(DISTINCT k.client_id) = 1 
    ) 
) 

最內層的子查詢取 「唯一」 的數字,例如號碼屬於只有一個客戶端。

中間內部子查詢僅從這些數字中提取屬於所需客戶端的子查詢(請注意k.client_id = 1)。

最後,外部查詢獲取消息,該號碼可以在該電話列表中找到。

有關性能的注意事項:如果您在client_id字段中放置索引,則中間子查詢可以。最內在的查詢有點問題,因爲它檢查關鍵字表的所有行。你的桌子上的size/number_of_rows怎麼樣?

希望它能幫助你。