简体   繁体   中英

SQL Query explanation with IF and INNER JOIN

Could someone please explain this SQL to me, I'm trying to edit code but I don't understand this.
This is the whole 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

I don't understand this part:

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

In case you don't understand INNER JOIN , here's a good explanation . It's basically an intersection, produced by doing a CROSS JOIN (ie Cartesian Product if you think of the tables as sets) and then filtering based on a condition specified in an ON clause.

The queries are using aliases: c and m respectively to make the overall query shorter. So, c is the result of:

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

and m is the result of:

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

and the ON clause is filtering the results of the CROSS JOIN of the two queries based on whether the conversation_id column's value from query c is equal to the conversation_id column's value from query m .

The WHERE , AND and GROUP BY clauses after the INNER JOIN are simply part of the SELECT that are filtering the results after the INNER JOIN occurs.

The IF is pretty simple too:

IF(expr1,expr2,expr3)

If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2 ; otherwise it returns expr3 .

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

Seems like this would do the same thing...

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

...although you won't know which conversation_id attained which count!?!

It is doing a subquery (after the keywords INNER JOIN ), its result is like "a table" but it is created "on the fly", and its alias is "m".

Once you know how this subquery works, you are doing an inner join of your table "c" with the new table "m" joining by keys m.conversation_id and c.conversation_id . So you are joining conversations from different sources.

The where part is just a filter applied to the output, it depends on the content of the fields.

If you have any other question, just leave a comment ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM