我有一个events
表,其中包含一个名为breaks
的字段。这是以逗号分隔格式填充的数据,即1,2,3
或1
或1,4,5
- 与MySQL的IN
命令使用的格式相同。
然后,我想在slots
表上运行查询,以返回events.breaks
中指定的所有行。
理论上,查询应该是这样的:
SELECT
`slots`.`id` AS id,
RIGHT(`slots`.`time`, 8) AS `time`
FROM
`slots`, `event`
WHERE
`slots`.`id` NOT IN (`event`.`breaks`)
但这似乎不起作用 - 如果event.breaks
是4,5,7
,slots
表中唯一不返回的行是4
!
SQLFiddle:http://sqlfiddle.com/#!2/913fe/1/0
答案 0 :(得分:3)
您将单个字段传递给NOT IN()子句,而不是子表达式。可以这样想想
(1, 2, 3)
与
大致相同SELECT 1
UNION
SELECT 2
UNION
SELECT 3;
作为子表达式。你正在做的是
('4,5,7')
大致相当于
SELECT '4,5,7';
反过来,MySQL可能转换为数字进行比较,结果是
NOT IN (4)
你真正想做的事情并不是真的应该这样做。如果你添加了一个AxB关系表,那就更好了,这样就可以用你不想要的ID选择几行。
答案 1 :(得分:2)
尝试一下:
SELECT slots.id AS id, RIGHT(slots.time, 8) time
FROM slots, event
WHERE FIND_IN_SET(slots.id, event.breaks) = 0
这就是FIND_IN_SET(str,strlist)
函数的工作原理:
如果字符串str位于由N个子字符串组成的字符串列表strlist中,则返回1到N范围内的值。字符串列表是由用“,”字符分隔的子字符串组成的字符串。 [...]如果str不在strlist中,或者strlist是空字符串,则返回0。
另请注意,IN (val1, val2, val3)
与IN (val4)
不同,其中val4
是以逗号分隔的字符串。 IN子句将通过相等进行比较。
答案 2 :(得分:0)
您可能需要使用子选择来返回拆分字符串
... NOT IN (SELECT your_split_fnc(`event`.`breaks`) FROM `events`)
请在此处查看答案,了解在MySQL Can Mysql Split a column?
中拆分字符串的方法instr()MySQL函数也可以提供帮助
... INSTR(event.breaks,id) = 0
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_instr