2009-10-18 89 views
7

目前,我有我的表中的一行:MySQL的Select語句,其中 'IN' 條款

  course_data: 
      user_id  days  <-- This is a varchar column. 
       405   1,3,5 

,我想實現下面的SELECT語句:

SELECT usrID, usrFirst, usrLast, usrEmail 
    FROM tblUsers 
    WHERE usrID NOT IN 
    (
     SELECT users.usrID 
      FROM 
       `course_data` courses, 
       `tblUsers` users 
      WHERE 
       days IN ('$day') 
    ) 
    GROUP BY usrID 
    ORDER BY usrID 

基本上,我如果$ day變量包括'1,3或5',則希望該行(用戶405)被省略。

例如,如果$day = "1",它應該返回一個空查詢(因爲數字「1」在列「1,3,5」)。

但是,我還沒有發現這種情況。即使$day = "1",它仍然返回該行。

它不會返回行的唯一方法是如果​​然而,我認爲IN()子句將採用我的變量的任何部分,並將其應用於該列。

任何有關我在做什麼錯誤的見解?謝謝。

回答

11

您應該使用the like keyword做煤焦領域的一個部分匹配:

where days like '%1%' 

編輯: VolkerK和盧卡斯·拉林斯基都建議MySQL的find_in_set,這可能比你想要做的like更好。但是,以下有關規範化數據庫的建議仍然適用。

但是,不應將多個值存儲在單個數據庫字段中。相反,可以考慮使用兩個表:

course_data: 
    user_id 

course_days: 
    user_id 
    day_number 

然後,您將有以下數據:

course_data: 
    user_id 
    405 

course_days 
    user_id day_number 
    405  1 
    405  3 
    405  5 

然後,您可以正確查詢此架構。例如:

select cd.user_id 
from course_data as cd 
where cd.user_id not in 
    (
     select course_days.user_id 
     from course_days 
     where course_days.user_id = cd.user_id 
      and course_days.day_number = 1 
    ) 

(或者,這應該是接近,我不正是務必要完成什麼,或者你的架構其餘的樣子,所以這是一個最好的猜測) 。

+0

謝謝。你對改變結構是正確的。我繼續這樣做。謝謝。 – Dodinas 2009-10-18 22:08:00

+0

「所以這是最好的猜測」:另一個(希望可行的)想法是使用NOT EXISTS子查詢,如http://dev.mysql.com/doc/refman/5.1/en/exists-and-not- exists-subqueries.html而不是'x NOT IN(subquery)' – VolkerK 2009-10-19 08:30:08

+0

%like%會給11搜索1,所以它不適合,所以這個答案並不適用於原始問題。 theomega的答案似乎更適用於OP。 – Tarquin 2017-09-10 23:53:38

14

刪除IN語句中的行情。語法是:

... WHERE column IN (1,2,3) 

而不是你用它

... WHERE column IN ('1,2,3') 

也可見於documentation,還有更多的例子。

+0

其實,對不起,我需要一些澄清。我在這裏做錯了事。如果我使用:WHERE IN IN(1)天,它會正確刪除它並返回空結果。但是,如果我使用:WHERE IN(3)天,它不會返回空查詢。我會認爲它應該刪除查詢,因爲'3'在查詢中?有任何想法嗎? – Dodinas 2009-10-18 21:43:52

+0

我想這是因爲它將「1,3,5」轉換爲int(以逗號停留),然後看到它匹配。 – Yuliy 2009-10-18 21:45:58

+0

不知道爲什麼這不是原始文章中給出的方案的接受答案 - 儘管我接受接受的答案提供了糾正錯誤編碼習慣的建議。 – Tarquin 2017-09-10 23:51:50

0

天不包含字符串列表。它包含一個字符串。 {'1'}中的字符串之一是字符串「1,3,5」嗎?很明顯,答案是否定的。無論是重構天到一個不同的表,或者準備做更多的字符串操作

2

如果我正確理解您的問題,您希望將varchar字段的內容視爲逗號分隔列表,並測試此列表是否不包含特定值。爲此,您需要find_in_set(str, strlist)函數。
但請記住,在這種情況下,MySQL不能使用索引,並且您的查詢將始終需要全表掃描。它可能最好不要將結構化數據(並在單個元素上運行比較)存儲在單個列中,而是使用其他響應中建議的另一個表和JOIN。

5

我想你想查詢的是:

SELECT usrID, usrFirst, usrLast, usrEmail 
FROM tblUsers 
WHERE usrID NOT IN (
    SELECT user_id 
    FROM course_data 
    WHERE find_in_set(?, days) > 0 
) 
ORDER BY usrID 

但是你應該認真考慮標準化的數據庫,讓每一天都有它自己的行。