使用IF和INNER JOIN进行SQL查询说明

时间:2014-03-05 14:37:16

标签: mysql

有人可以向我解释这个SQL,我正在尝试编辑代码,但我不明白这一点 这是整个sql:

SELECT SQL_CACHE COUNT(c.conversation_id) AS num_messages
                FROM table1 AS c
                INNER JOIN (
                    SELECT message_id,conversation_id FROM table2
                    WHERE recipient_id=:userid  ORDER BY created DESC
                ) AS m ON(m.conversation_id=c.conversation_id)
                WHERE (c.initiator_id=:userid OR c.interlocutor_id=:userid)
                AND (c.bm_read & IF(c.initiator_id=:userid, :bminit, :bminter)) = 0
                AND (c.bm_deleted & IF(c.initiator_id=:userid, :bminit, :bminter)) = 0
                GROUP BY c.conversation_id

我不明白这一部分:

INNER JOIN  (
             SELECT message_id,conversation_id FROM table2
              WHERE recipient_id=:userid  ORDER BY created DESC
            ) AS m ON(m.conversation_id=c.conversation_id)
            WHERE (c.initiator_id=:userid OR c.interlocutor_id=:userid)
            AND (c.bm_read & IF(c.initiator_id=:userid, :bminit, :bminter)) = 0
            AND (c.bm_deleted & IF(c.initiator_id=:userid, :bminit, :bminter)) = 0

3 个答案:

答案 0 :(得分:1)

如果您不理解INNER JOINhere's a good explanation。它基本上是一个交集,通过执行CROSS JOIN生成(如果您将表视为集合,则为Cartesian Product),然后根据ON子句中指定的条件进行过滤。

查询分别使用别名cm来缩短整体查询。因此,c是以下结果:

SELECT SQL_CACHE COUNT(c.conversation_id) AS num_messages
FROM table1

m是以下结果:

SELECT message_id,conversation_id FROM table2
WHERE recipient_id=:userid  ORDER BY created DESC

并且ON子句根据查询CROSS JOIN中的conversation_id列的值是否等于{{}来过滤两个查询的c的结果1}}来自查询conversation_id的列的值。

m之后的WHEREANDGROUP BY条款只是INNER JOIN的一部分,正在过滤结果之后 SELECT发生。

INNER JOIN也很简单:

IF

如果 expr1 为TRUE(expr1<> 0且expr1<> NULL),则IF()返回 expr2 ;否则返回 expr3

https://dev.mysql.com/doc/refman/5.1/en/control-flow-functions.html#function_if

答案 1 :(得分:0)

似乎这样会做同样的事情......

SELECT COUNT(c.conversation_id) num_messages
  FROM conv c
  JOIN TBL_MSG m
    ON m.conversation_id = c.conversation_id
 WHERE m.recipient_id = :userid
   AND :userid IN (c.initiator_id,c.interlocutor_id)
   AND c.bm_read    & IF(c.initiator_id=:userid, :bminit, :bminter)) = 0 -- I don't understand 
   AND c.bm_deleted & IF(c.initiator_id=:userid, :bminit, :bminter)) = 0 -- this bit.
 GROUP 
    BY c.conversation_id

...虽然你不知道哪个conversation_id达到了哪个数量!?!

答案 2 :(得分:0)

正在执行子查询(在关键字INNER JOIN之后),其结果类似于“一个表”,但它是“动态”创建的,其别名为“m”。

一旦你知道这个子查询是如何工作的,你就可以通过键m.conversation_idc.conversation_id来加入表“c”与新表“m”的内连接。所以你正在加入来自不同来源的对话。

where部分只是应用于输出的过滤器,它取决于字段的内容。

如果您有任何其他问题,请发表评论; - )