2014-09-06 32 views
1

請檢查下面多對多的MySQL棘手的條件

用戶我的表

id name 
1 John 
2 Peter 
3 Predator 

手機

id name 
1 apple 
2 nexus 
3 nokva 

phones_users

phone_id user_id 
1  1 
2  1 
2  2 
3  3 

sqlfiddle

好吧,我想這樣的結果:

phone_id phone_name user_id user_name 
1   apple  1  John 
2   nexus  1  John 
2   nexus  2  Peter 

我試過一個請求,但它不工作果然

select `phones`.`name` as `phone_name`, `phones`.`created_at`, `phones`.`id`, `users`.`name` as `user_name`, `users`.`id` as `user_id` from `phones` left join `phones_users` on (`phones`.`id` = `phones_users`.`phone_id` and `phones_users`.`user_id` = 1) left join `users` on `phones_users`.`phone_id` = `phones`.`id` where `users`.`name` is not null; 

我想所有具有手機ID = 1的用戶以及所有擁有屬於他的電話的用戶。

例如,John有蘋果和nexus,Peter有nexus,我想用蘋果,nexus,John,Peter 。

THANKS

回答

1

我連着phones_users的副本,並使用IF區分,手機是否屬於同一人或沒有。根據我輸出的用戶名和ID。

SELECT 
    `phones_users`.`phone_id`, 
    `phones`.`name` AS phone_name, 
    IF(`users`.`id` = `users2`.`id`, `users`.`id`, `users2`.`id`) 
     AS `user_id`, 
    IF(`users`.`id` = `users2`.`id`, `users`.`name`, `users2`.`name`) 
     AS `user_name` 
FROM 
    phones_users 
INNER JOIN 
    phones 
ON 
    phones_users.phone_id=phones.id 
INNER JOIN 
    users 
ON 
    phones_users.user_id=users.id 
INNER JOIN -- here I attach the copy of the table 
    phones_users AS phones_users2 
ON 
    phones_users.phone_id=phones_users2.phone_id 
INNER JOIN 
    users AS users2 
ON 
    phones_users2.user_id=users2.id 
WHERE 
    phones_users.user_id=1; 

輸出:

+----------+--------------+---------+-----------+ 
| phone_id | phone_name | user_id | user_name | 
+----------+--------------+---------+-----------+ 
|  1 | apple iphone |  1 | John  | 
|  2 | nexus  |  1 | John  | 
|  2 | nexus  |  2 | Peter  | 
+----------+--------------+---------+-----------+ 
+0

它的工作原理!非常感謝!你真棒 – 2014-09-07 05:29:42

1
-- We know the user details for this part of the query, so just hard-code them instead of query for them 
    SELECT phone_id, (SELECT name FROM phones WHERE id = pu.phone_id) AS phone_name, 1 AS user_id, "John" AS user_name 
    FROM phones_users pu 
    WHERE phone_id IN (SELECT phone_id 
         FROM phones_users 
         WHERE user_id = 1) 
UNION ALL 
    SELECT p.id AS phone_id, p.name AS phone_name, u.id AS user_id, u.name AS user_name 
    FROM phones p, user u 
    WHERE u.id IN (SELECT user_id 
        FROM phones_users 
        WHERE user_id != 1 
        AND phone_id IN (SELECT phone_id FROM phones_users WHERE user_id = 1)) 
     AND u.id = (SELECT user_id 
        FROM phones_users 
        WHERE phone_id = p.id) 

轉錄成英語:

從表中選擇phones_users,其中此ID是由約翰和使用手機的ID列表中phone_id的帶有此ID的電話名稱和值1(John的ID)和他的名字「John」。 然後,追加到(在這裏開始變得更加複雜): 電話ID和名稱以及來自加入表phonesusers的行所產生的行的名稱,但僅在滿足以下約束的行上:

  • 行的用戶ID的用戶,其手機的ID是一樣的手機約翰(id爲1的用戶)使用的ID的用戶ID列表,即該用戶是不是約翰而是使用與John相同的電話,
  • 並且用戶ID在與表格phones_users中的用戶ID列表中位於與連接行的電話ID相同的行中,即,該用戶確實使用該電話(加入表phonesusers將提供所有可能的組合,因此我們必須刪除人們使用他們不使用的電話的行)。

我希望你能理解轉錄和查詢,如果不能隨意發表評論。

免責聲明:我沒有測試查詢,它可能無法正常工作。

+0

謝謝!我試過你的例子,並得到這個「參考'phone_name'不支持(項目列表中的前向參考):SELECT phone_id,(SELECT phone_name FROM phones WHERE id = pu.phone_id)AS phone_name,1 AS user_id,」John「AS user_name FROM phone_users pu WHERE phone_id IN(SELECT phone_id FROM phones_users WHERE user_id = 1)UNION ALL SELECT p.id AS phone_id,p.name AS phone_name,u.id AS user_id,u.name AS user_name FROM phones p,users u WHERE u。 id IN(SELECT user_id FROM phones_users WHERE user_id!= 1 ...「 – 2014-09-07 05:29:00

+0

@JohnSmitt哎呀,那'phone_name'應該只是'name',我會編輯。 – 11684 2014-09-07 05:31:34