1

我将一些数据存储在 MySQL 中,并希望过滤掉与给定条件匹配的行。

听起来很容易,但这并不容易,因为涉及到一些加入标准。

我确实有以下表格:

items : id, ...
genres: id, name:varchar, item_id

每个项目都有多个流派。

如果至少一个流派确实与给定的流派名称(或一组名称)匹配,则查询应该过滤掉项目。

例如:

Item with id 1 has 3 genres
  - genre name = 'foo'
  - genre name = 'bar'
  - genre name = 'baz'

如果给定的流派名称是 'bar'、['bar'、'baz'、'xyz'] 等,则项目 1 可能不是结果集的一部分。

我试图离开加入项目的流派并应用带有“genres.name NOT IN (?)”的 WHERE 语句。? 是给定的流派名称集。

这(当然)只适用于只有一种类型的项目。同样可以通过多个 WHERE 条件来实现: WHERE name <> 'a' AND name <> 'b' ...

任何想法如何正确完成此查询?

提前致谢!

4

4 回答 4

1

你可以做这样的事情(见 sqlfiddle):

select i.name as item, g.name as genre
from items as i
left join genres as g
  on i.id = g.item_id 
where i.id not in
      (select distinct g2.item_id from genres as g2
       where FIND_IN_SET(g2.name,'foo,bar'));

如果您想检查多个流派名称,这种方式就可以工作。

于 2012-06-14T17:42:39.180 回答
0

您可以使用相关子查询。
例子:

SELECT id 
FROM   items i
WHERE  NOT EXISTS (SELECT 1 
                   FROM   genres g
                   WHERE  g.`name` = 'bar' 
                   AND    i.id = g.item_id);

相关子查询与其他子查询的不同之处在于它引用了外部查询。
为外部查询投影/选择的每一行运行相关子查询。

于 2012-06-14T17:40:03.627 回答
0

好吧,希望我能理解您的要求,并且我认为 MySQL 和 T-SQL 在这方面将是相似的。这些是我假设您在示例中使用的示例表。

Table1
ID  NAME
1   Item 1
2   Item 2
3   Item 3
4   Item 4
5   Item 5
6   Item 6

Table2
ID  NAME    ITEM_ID
1   Genre 1   1
2   Genre 2   1
3   Genre 3   1
4   Genre 1   2
5   Genre 2   2
6   Genre 3   2
7   Genre 1   3
8   Genre 2   3
9   Genre 3   3
10  Genre 1   4

如果项目符合您的条件之一,这是过滤掉项目的 SQL。

SELECT *
FROM table1 a, table2 b
WHERE a.id = b.item_id
AND b.name NOT IN ('Genre 1', 'Genre 2')

从上述示例表查询返回的结果。

ID  NAME    ID_1    NAME_1  ITEM_ID
1   Item 1    3 Genre 3   1
2   Item 2    6 Genre 3   2
3   Item 3    9 Genre 3   3

您也可以过滤掉genre_id (table2.id)。如果您打算使用子查询而不是硬编码值,那么您应该将“NOT IN”切换为“NOT EXISTS”并相应地重写“AND”部分,因为“NOT IN”不喜欢空值。

此查询还假定每个“项目”至少有 1 个“流派”。如果您想要所有“项目”(不包括符合您条件的项目),我相信您可以使用它。

于 2012-06-14T18:05:46.877 回答
0
select * from items i where not exists 
(select '' from genres gen where gen.item_id = i.id and gen.name in ('foo','pop') )

A shorter ans simpler query. The inner query checks genre name in the keywords list , if the no row is returned then the current row of outer query is selected.
Verify the output at here.

Thanks to Kyra ,i borrowed his schema from sql fiddle.

于 2012-06-14T18:07:31.350 回答