Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.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 Match All - Fatal编程技术网

强制mySQL加入表(执行我需要的未优化查询)

强制mySQL加入表(执行我需要的未优化查询),mysql,sql-match-all,Mysql,Sql Match All,这有点奇怪。我有下一个问题: SELECT * , GROUP_CONCAT( x.tag SEPARATOR ',' ) AS tags FROM tag AS t, tag AS x, tag_message_rel AS r, message m INNER JOIN `user` AS u ON m.user_id = u.id WHERE t.tag IN ( 'kikikiki', 'dsa' ) AND m.id = r.message_id AND t.id = r.tag_id

这有点奇怪。我有下一个问题:

SELECT * , GROUP_CONCAT( x.tag
SEPARATOR ',' ) AS tags
FROM tag AS t, tag AS x, tag_message_rel AS r, message m
INNER JOIN `user` AS u ON m.user_id = u.id
WHERE t.tag
IN (
'kikikiki', 'dsa'
)
AND m.id = r.message_id
AND t.id = r.tag_id
AND x.id = r.tag_id
GROUP BY m.id
HAVING COUNT( * ) >=2
ORDER BY m.created_at DESC
LIMIT 0 , 20
正如您所看到的,我使用t来连接并查找我想要的消息,在另一侧,我使用x来打印消息的标记。我删除了这行:

AND x.id = r.tag_id
我会得到我想要的消息,但是标签会将标签表中的所有标签用逗号分隔。如果我把线留在那里,我只会得到那两个标签。 如果我使用explain,我会得到:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  u   system  PRIMARY     NULL    NULL    NULL    1   Using temporary; Using filesort
1   SIMPLE  t   range   PRIMARY,tag     tag     252     NULL    2   Using where
1   SIMPLE  x   eq_ref  PRIMARY     PRIMARY     4   verse.t.id  1    
1   SIMPLE  r   ALL     NULL    NULL    NULL    NULL    180     Using where; Using join buffer
1   SIMPLE  m   eq_ref  PRIMARY     PRIMARY     4   verse.r.message_id  1   Using where
现在我不是这方面的专家,但我认为问题在于它在优化查询的过程中拒绝重新连接表


你觉得怎么样?有什么快速解决方法吗?

您只会得到这两个标签,因为:

  • t、 标记入('kiki','dsa')。 2 t.id IN(Kiki的id,dsa的id)
  • t、 id=r.tag\u id
  • r、 tag_id=x.id
  • 组合3和4,t.id=x.id
  • 组合所有内容,x.tag IN('kiki','dsa')

  • 我想你想要的是加入第二个
    标记消息\u rel
    。将
    t
    连接到第一个;将
    x
    连接到第二个;将它们连接到
    消息
    。不完全确定这是您想要的,因为您实际上没有说…

    您只得到这两个标签,因为:

  • t、 标记入('kiki','dsa')。 2 t.id IN(Kiki的id,dsa的id)
  • t、 id=r.tag\u id
  • r、 tag_id=x.id
  • 组合3和4,t.id=x.id
  • 组合所有内容,x.tag IN('kiki','dsa')

  • 我想你想要的是加入第二个
    标记消息\u rel
    。将
    t
    连接到第一个;将
    x
    连接到第二个;将它们连接到
    消息
    。不完全确定这是您想要的,因为您实际上没有说…

    问题是您试图连接到
    标记表两次,但您确实需要连接到
    标记消息\u rel
    表两次,并从每一次连接到
    标记表中的相应行

    可以将“表别名”看作是指表中的一行,而不是表本身。这个想法帮助我更好地理解复杂连接

    下面是我如何编写该查询的:

    SELECT m.*, u.*, GROUP_CONCAT(DISTINCT x.tag) AS tags
    FROM message m
     JOIN `user` u ON (u.id = m.user_id)
     JOIN tag_message_rel r1 ON (m.id = r1.message_id)
     JOIN tag t ON (t.id = r1.tag_id)
     JOIN tag_message_rel r2 ON (m.id = r2.message_id)
     JOIN tag x ON (x.id = r2.tag_id)
    WHERE t.tag IN ('kikikiki', 'dsa')
    GROUP BY m.id
    HAVING COUNT(DISTINCT t.tag) = 2
    ORDER BY m.created_at DESC
    LIMIT 0 , 20;
    
    您应该养成一致使用
    JOIN
    语法的习惯。混合使用
    连接
    和逗号样式的连接可能会导致一些微妙的问题

    这里有一个替代查询,它将一些联接拉入一个不相关的子查询中,这样就避免了
    t
    x
    之间的笛卡尔乘积,并消除了组函数中的
    不同的
    修饰符

    SELECT m.*, u.*, GROUP_CONCAT(x.tag) AS tags
    FROM message m
     JOIN `user` u ON (u.id = m.user_id)
     JOIN tag_message_rel r ON (m.id = r.message_id)
     JOIN tag x ON (x.id = r.tag_id)
    WHERE m.id = ANY (
        SELECT m2.id 
        FROM message m2 
         JOIN tag_message_rel r2 ON (m2.id = r2.message_id)
         JOIN tag t ON (t.id = r2.tag_id)
        WHERE t.tag IN ('kikikiki', 'dsa') 
        GROUP BY m2.id 
        HAVING COUNT(t.tag) = 2)
    GROUP BY m.id
    ORDER BY m.created_at DESC
    LIMIT 0 , 20;
    

    问题是,您试图两次加入
    标记
    表,但确实需要两次加入
    tag\u message\u rel
    表,并从每一次加入到
    标记
    表中的相应行

    可以将“表别名”看作是指表中的一行,而不是表本身。这个想法帮助我更好地理解复杂连接

    下面是我如何编写该查询的:

    SELECT m.*, u.*, GROUP_CONCAT(DISTINCT x.tag) AS tags
    FROM message m
     JOIN `user` u ON (u.id = m.user_id)
     JOIN tag_message_rel r1 ON (m.id = r1.message_id)
     JOIN tag t ON (t.id = r1.tag_id)
     JOIN tag_message_rel r2 ON (m.id = r2.message_id)
     JOIN tag x ON (x.id = r2.tag_id)
    WHERE t.tag IN ('kikikiki', 'dsa')
    GROUP BY m.id
    HAVING COUNT(DISTINCT t.tag) = 2
    ORDER BY m.created_at DESC
    LIMIT 0 , 20;
    
    您应该养成一致使用
    JOIN
    语法的习惯。混合使用
    连接
    和逗号样式的连接可能会导致一些微妙的问题

    这里有一个替代查询,它将一些联接拉入一个不相关的子查询中,这样就避免了
    t
    x
    之间的笛卡尔乘积,并消除了组函数中的
    不同的
    修饰符

    SELECT m.*, u.*, GROUP_CONCAT(x.tag) AS tags
    FROM message m
     JOIN `user` u ON (u.id = m.user_id)
     JOIN tag_message_rel r ON (m.id = r.message_id)
     JOIN tag x ON (x.id = r.tag_id)
    WHERE m.id = ANY (
        SELECT m2.id 
        FROM message m2 
         JOIN tag_message_rel r2 ON (m2.id = r2.message_id)
         JOIN tag t ON (t.id = r2.tag_id)
        WHERE t.tag IN ('kikikiki', 'dsa') 
        GROUP BY m2.id 
        HAVING COUNT(t.tag) = 2)
    GROUP BY m.id
    ORDER BY m.created_at DESC
    LIMIT 0 , 20;