Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在一对多表设计中选择缺少值_Mysql_Sql - Fatal编程技术网

Mysql 在一对多表设计中选择缺少值

Mysql 在一对多表设计中选择缺少值,mysql,sql,Mysql,Sql,我整天都在研究一个我认为很简单的问题,但事实证明这个问题令人难以置信地难以捉摸。我怀疑我问的问题可能不对,所以请容忍我 我有一张桌子,桌上放着一堆研究项目的报纸文章。这个想法是,研究人员可以标记单个文章。这些标记存储在第二个表中。一篇文章可以有任意数量的标签 然后,我可以使用选择带有特定标签的文章 SELECT *, GROUP_CONCAT(`TAGS`.`TAG`) AS tags FROM ARTICLES LEFT JOIN TAGS

我整天都在研究一个我认为很简单的问题,但事实证明这个问题令人难以置信地难以捉摸。我怀疑我问的问题可能不对,所以请容忍我

我有一张桌子,桌上放着一堆研究项目的报纸文章。这个想法是,研究人员可以标记单个文章。这些标记存储在第二个表中。一篇文章可以有任意数量的标签

然后,我可以使用选择带有特定标签的文章

SELECT *, 
       GROUP_CONCAT(`TAGS`.`TAG`) AS tags 
FROM   ARTICLES 
       LEFT JOIN TAGS 
               ON TAGS.ID = ARTICLES.ID 
WHERE  TAGS.TAG = 'search term' 
GROUP  BY ARTICLES.ID; 
当我想基于缺少特定标记来选择文章时,我的问题就开始了。如果一篇文章只有一个标记,则结果与预期一致,但是如果一篇文章关联了多个标记,则该标记将被简单地忽略

SELECT *, 
       GROUP_CONCAT(`TAGS`.`TAG`) AS tags 
FROM   ARTICLES 
       LEFT JOIN TAGS 
               ON TAGS.ID = ARTICLES.ID 
WHERE  TAGS.TAG != 'search term' 
        OR TAGS.TAG IS NULL 
GROUP  BY ARTICLES.ID; 
如果原始表格如下所示

ID               Name
1                Article #1
2                Article #2

然后,如果我使用上面的查询来选择标记在何处的文章!=无聊,结果会是

ArticleID        Name          Tags
1                Article #1    New, Long
2                Article #2    Old, Long, Interesting
我怎样才能让它完全排除第一篇文章,而不是仅仅排除那个标签?请记住,数据库中有超过十万篇文章,最有效的方法是什么?我看了几十个其他问题和谷歌搜索,但选择没有这样的标签是我找不到的建议

另一方面,我目前使用的是一对多表,因为每个标记在链接到的每一篇文章中都会出现一次。我注意到很多人在类似的场景中使用多对多设计。这是否比在引用article表的tags表中只有一个外键快得多

感谢您帮助解决SQL noob:)。

试试这个:

SELECT  A.ID, 
        A.`Name`,
        GROUP_CONCAT(`TAGS`.`TAG`) AS tags 
FROM   ARTICLES A
       LEFT JOIN TAGS 
               ON TAGS.ID = A.ID 
WHERE   NOT EXISTS( SELECT 1 FROM TAGS 
                    WHERE ID = A.ID
                    AND Tag = 'search term')
GROUP  BY ARTICLES.ID, ARTICLES.`Name`; 

我会这样做:

SELECT *, 
       GROUP_CONCAT(`TAGS`.`TAG`) AS tags 
FROM   ARTICLES A
       LEFT JOIN TAGS 
           ON TAGS.ID = ARTICLES.ID 
WHERE A.ID NOT IN (
    SELECT ArticleID FROM TAGS
    WHERE Tag = 'search term'
)
GROUP BY A.ID;

左连接。。。在x=x和y=y上,其中y为空;对,这是我盯着看了几个小时的结果。我使用的SQL已经使用了左连接,这里输入错误。@草莓,我仍然不明白你要用这个做什么。x和y在这里代表什么?在TAGS.ID=ARTICLES.ID和TAGS.TAG='search term'上,删除TAGS.TAG='search term'后,这似乎起作用。我要再仔细研究一下,然后再回来选择答案。@Fluffy是的,对不起,这是错误的。这是个人偏好,还是比存在更快?事实上,我不知道
存在
可以用这种方式使用(只有在表存在的情况下才知道)。读了一些关于它的文章后,我猜测
EXISTS
可能会更快,因为您没有将A.ID与子查询进行比较。
SELECT *, 
       GROUP_CONCAT(`TAGS`.`TAG`) AS tags 
FROM   ARTICLES A
       LEFT JOIN TAGS 
           ON TAGS.ID = ARTICLES.ID 
WHERE A.ID NOT IN (
    SELECT ArticleID FROM TAGS
    WHERE Tag = 'search term'
)
GROUP BY A.ID;
SELECT  A.ID, 
        A.`Name`,
        GROUP_CONCAT(`TAGS`.`TAG`) AS tags 
FROM   ARTICLES A
       LEFT JOIN TAGS 
 ON TAGS.ID = A.ID 

LEFT JOIN  (
    SELECT ArticleID FROM TAGS LKP
    WHERE Tag = 'search term'
) SRCH
 ON SRCH. ArticleID =A.ID
WHERE SRCH. ArticleID IS NUll