简体   繁体   中英

How can convert conditioned inner query to LEFT JOIN in MYSQL?

I have a query like this

SELECT * FROM CC 
INNER JOIN App (CC.id = App.id)   
WHERE CC.counter >1000
AND 0 = IF(CC.key1 = App.key1,
                    (SELECT COUNT(*)
                        FROM Service
                        WHERE App.No = Service.No
                     )
                    ),
                    (SELECT COUNT(*)
                        FROM Service
                        WHERE App.NoCo = Service.No
                        AND App.NoCo != ''
                      )
                    )
                )

How can convert conditioned inner query to LEFT JOIN in MYSQL ?

I am trying to convert this sub-query to join clause for better performance

Try this:

SELECT * FROM CC 
INNER JOIN App (CC.id = App.id)   
LEFT JOIN(SELECT s.no,count(*) as cnt_1,sum(s.no <> '') as cnt_2
          FROM Service s
          GROUP BY s.no) t
 ON(0 = CASE WHEN CC.key1 = App.key1 THEN t.cnt_1 ELSE t.cnt_2 END)
WHERE CC.counter >1000

I would instead use EXISTS :

SELECT *
FROM CC INNER JOIN
     App
     ON CC.id = App.id 
WHERE CC.counter > 1000 AND
      ( (CC.key1 = App.key1 AND
         NOT EXISTS (SELECT 1
                     FROM Service
                     WHERE App.No = Service.No
                    ) OR
        (CC.key1 = App.key1 AND
         NOT EXISTS (SELECT 1
                     FROM Service
                     WHERE App.NoCo = Service.No AND
                           App.NoCo <> ''
                    )
         )
        );

For performance, you want an index on Service(No) and CC(counter, id) .

You have to be careful with a LEFT JOIN , because your conditions have an OR . This can inadvertently multiply the number of rows.

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