在构建更大,更高级的Web应用程序时,我发现自己正在编写极其漫长而复杂的查询。我倾向于在查询中编写很多查询,因为我觉得从PHP一次调用数据库要比多次调用和关联数据更好。
但是,任何对SQL有任何了解的人都对JOINs有所了解。就个人而言,我曾经使用过一JOIN两个,但是当我发现使用子查询时很快就停下来了,因为它对我来说编写和维护起来更加容易和快捷。
JOIN
通常,我会做一些子查询,其中可能包含相对表中的一个或多个子查询。 考虑以下示例:
SELECT (SELECT username FROM users WHERE records.user_id = user_id) AS username, (SELECT last_name||', '||first_name FROM users WHERE records.user_id = user_id) AS name, in_timestamp, out_timestamp FROM records ORDER BY in_timestamp
很少,我将在该WHERE子句之后进行子查询。 考虑以下示例:
WHERE
SELECT user_id, (SELECT name FROM organizations WHERE (SELECT organization FROM locations WHERE records.location = location_id) = organization_id) AS organization_name FROM records ORDER BY in_timestamp
在这两种情况下,如果我决定使用JOIN?重写查询,我会看到任何改进吗?
作为一个笼统的问题,使用子查询或a的优点/缺点是JOIN什么?一种方法比另一种更正确或被接受吗?
最好使用JOIN来分隔[子]查询。 如果子选择(AKA子查询)与外部查询不相关,则优化程序很可能会扫描一次子选择中的表,因为该值不太可能改变。当您具有相关性时(如提供的示例中所示),单遍优化的可能性变得非常小。过去,人们相信会执行相关的子查询,即RBAR- 通过逐行行化。使用JOIN,可以确保在表格上进行一次传递,同时获得相同的结果。
这是对提供的查询的正确重写:
SELECT u.username, u.last_name||', '|| u.first_name AS name, r.in_timestamp, r.out_timestamp FROM RECORDS r LEFT JOIN USERS u ON u.user_id = r.user_id ORDER BY r.in_timestamp
…因为如果USERS表中不存在user_id,则subselect可以返回NULL 。否则,您可以使用INNER JOIN:
USERS
SELECT u.username, u.last_name ||', '|| u.first_name AS name, r.in_timestamp, r.out_timestamp FROM RECORDS r JOIN USERS u ON u.user_id = r.user_id ORDER BY r.in_timestamp
派生表/内联视图也可以使用JOIN语法。