2017-01-05 137 views
1

編輯:我似乎不正確地問這個問題。哪裏(設置)IN(設置)

我試圖找到一種方法來查詢,如果一套在另一套可用。例如:

SELECT * FROM something 
WHERE (1, 3) IN (1, 2, 3, 4, 5) 

在這種情況下,1 & 3是在集合(1,2,3,4,5)。又如:

SELECT * FROM something 
WHERE (1, 3) IN (1, 5, 7, 9); 

在這種情況下,1 & 3在設定不(1,5,7,9),所以沒有什麼應該從表中可以拉動。

+1

這似乎是問同樣的,並已解決了這個此前一天 - [MySQL的多個IN條件與同桌子查詢(http://stackoverflow.com/ question/41480785/mysql-multiple-in-conditions-to-subquery-with-same-table) – DanFromGermany

回答

1

新的要求(根據sqlfiddle.com/#!9/f36d92/2):

 
# The goal is to write a query that will select all exercises 
# that the user has the correct equipment for, where the pre-defined 
# set is the id's of the equipment the user has. 

# For example, let's assume the user has equipment (1, 4) 
# The exercise "Curls" should be pulled from the table, as the user has all 
# of the required equipment based on the exercise_requirements table. 
# while "Wrecking Ball" is not returned as the user only has a portion of the 
# required equipment. 

# If the user's equipment was (1, 3, 4) then both "Curls" and "Wrecking ball" 
# would be returned from the exercises table, as the user has the required equipment 
# for both exercises. 

#---- 

#Below is my take on your query. 
SELECT ex.* FROM exercises ex 
WHERE ex.id IN (
    SELECT exercise_id FROM exercise_requirements 
    WHERE ex.id IN (1, 4) 
    GROUP BY exercise_id 
    HAVING COUNT(distinct exercise_id) = 3 
); 

SOLUTION:

您在這裏混淆了一些標識。這將更接近:

SELECT ex.* FROM exercises ex 
WHERE ex.id IN (
    SELECT exercise_id FROM exercise_requirements 
    WHERE equipment_id IN (1, 4) 
    GROUP BY exercise_id 
    HAVING COUNT(distinct equipment_id) = 2 
); 

但仍然這個查詢是反之亦然。我們不想知道用戶的所有設備是否都存在於一套鍛鍊所需的設備中,但是否需要進行鍛鍊的整套設備是在用戶的設備中找到的。

可能最簡單的寫法是:合計exercise_requirementsexercise_id並檢查沒有equipment_id是用戶不需要的。

select * 
from exercises 
where id in 
(
    select exercise_id 
    from exercise_requirements 
    group by exercise_id 
    having sum(equipment_id not in (1, 4)) = 0 
); 

您更新小提琴:http://sqlfiddle.com/#!9/f36d92/5

+0

絕對天才。有時候想到盒子外面。我很有決心讓「Y號碼中的X號碼」收集到NOT IN Y號碼的總和甚至沒有超出我的想法。 – Hobbyist

0

您可以使用此

SELECT u.* 
FROM users u 
INNER JOIN completed_levels cl 
ON cl.user_id = u.id 
WHERE cl.id IN (1, 5, 7); 

或者使用EXISTS作爲link從@DanFromGermany

+1

這不起作用,這將返回已完成級別1,5或7的所有用戶。查詢需要選擇用戶已經完成了1,5和7級。 – Hobbyist

0

您可以使用Case做出Sum將與1增加1內的每個級別,5 & 7。

SELECT A.* FROM users AS 
INNER JOIN 
(
SELECT U.id, 
SUM(CASE WHEN 
     (
     A.completed_levels = 1 
     OR A.completed_levels = 5 
     OR A.completed_levels = 7 
    ) THEN 1 ELSE 0 END 
    ) AS RN 
FROM completed_levels A 
INNER JOIN users U ON A.user_id = U.id 
GROUP BY U.id 
) B ON A.id = B.id 
WHERE B.RN = 3 -- Those users have completed level 1, 5 & 7 will have RN = 3 only 
+0

我似乎是錯誤地問了這個問題。我的問題實際上是如何確保所有的集合都包含在不同的集合中。例如,'WHERE(1,5)IN(1,2,3,4,5,6,7)'是真的,'WHERE(1,5)IN(1,2,4,7, 8)'會是假的。查詢需要動態構建,所以我試圖避免一堆'AND'調用。 – Hobbyist

1

您正在使用IN子句相關的子查詢(即,子查詢引用u.id)。這不是我們如何使用它。 IN子句適用於不相關的子查詢;如果您需要相關子查詢,請改用EXISTS。對於您的問題,非相關子查詢就足夠了,所以用IN相應:

select * 
from users 
where u.id in (select user_id from completed_levels where id in (1, 5, 7); 

如果用戶必須擁有所有級別:

select * 
from users 
where u.id in (select user_id from completed_levels where id = 1 
    and u.id in (select user_id from completed_levels where id = 5 
    and u.id in (select user_id from completed_levels where id = 7; 

這樣的問題通常是更好地與聚集,從而解決不必一次又一次查詢同一表:

select * 
from users 
where u.id in 
(
    select user_id 
    from completed_levels where id in (1, 5, 7) 
    group by user_id 
    having count(distinct id) = 3 
); 
+0

我似乎不正確地問了這個問題。我的問題實際上是如何確保所有的集合都包含在不同的集合中。例如,WHERE(1,5)IN(1,2,3,4,5,6,7)爲真,WHERE(1,5)IN(1,2,4,7,8)爲是假的。查詢需要動態構建,所以我試圖避免一堆AND調用。 – Hobbyist

+0

好的,我現在明白了。請看我更新的答案。 –

+0

請檢查我的評論中反映的問題編輯。 +1爲不正確問題的答案。 – Hobbyist

4

注意:這回答了原來的問題,這似乎與OP修改後的問題無關。

你可以得到誰完成所有三個級別使用的用戶:

SELECT cl.user_id 
FROM completed_levels cl 
WHERE cl.id IN (3, 5, 7) 
GROUP BY cl.user_id 
HAVING COUNT(DISTINCT cl.id) = 3; 

(注:DISTINCT是沒有必要的,如果給定用戶的ID是唯一的)

然後,您可以得到你想要使用JOIN或類似的結構是什麼:

SELECT u.* 
FROM users u JOIN 
    (SELECT cl.user_id 
     FROM completed_levels cl 
     WHERE cl.id IN (3, 5, 7) 
     GROUP BY cl.user_id 
     HAVING COUNT(DISTINCT cl.id) = 3 
    ) cu 
    ON cl.user_id = u.id; 
+0

ahhh !!總是解決方案自帶@Gordon ... – Esty

+0

真的,@Gordan有智力回答。致敬&+1 – Susang

+0

嘿@Gordon,謝謝你的回答,我似乎在您點擊發送後立即發佈我的編輯內容,您是否介意查看問題編輯?我在沒有意識到的情況下提出了錯誤的問題,或者更確切地說是錯誤地提出了問題 謝謝。 – Hobbyist