将 SQL 重写为 JOINS 而不是子查询

发布于 2024-10-01 12:51:51 字数 676 浏览 2 评论 0原文

我在使用联接而不是两个子查询重写此查询时遇到一些麻烦。如果你明白我的意思的话,我在解开它时遇到了问题。

SELECT o.order_id, n.title, c.first_name, t1.name, o.product_id,
    (SELECT ttd2.tid FROM term_data ttd2, term_node ttn2 WHERE ttd2.vid = 5 AND ttn2.nid = p.nid AND ttd2.tid=ttn2.tid) AS tid,
    (SELECT ttd4.name FROM term_data ttd4, term_node ttn4 WHERE ttd4.vid = 8 AND ttn4.nid = p.nid AND ttd4.tid=ttn4.tid) AS month
    FROM orders o, products p, node n, customers c, term_data t1, term_node t2
    WHERE o.product_id = p.nid
    AND p.nid = n.nid
    AND o.customer_email = c.customer_email
    AND t2.tid = t1.tid
    AND t1.vid = 6
    AND n.nid = t2.nid

你能帮忙吗?或者给出一些线索/提示。

I have some troubles re-writing this query to using joins instead of the two subqueries. I have a problem untangling it, if you know what i mean.

SELECT o.order_id, n.title, c.first_name, t1.name, o.product_id,
    (SELECT ttd2.tid FROM term_data ttd2, term_node ttn2 WHERE ttd2.vid = 5 AND ttn2.nid = p.nid AND ttd2.tid=ttn2.tid) AS tid,
    (SELECT ttd4.name FROM term_data ttd4, term_node ttn4 WHERE ttd4.vid = 8 AND ttn4.nid = p.nid AND ttd4.tid=ttn4.tid) AS month
    FROM orders o, products p, node n, customers c, term_data t1, term_node t2
    WHERE o.product_id = p.nid
    AND p.nid = n.nid
    AND o.customer_email = c.customer_email
    AND t2.tid = t1.tid
    AND t1.vid = 6
    AND n.nid = t2.nid

Can you help? Or give some clues/hints.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半葬歌 2024-10-08 12:51:51

使用 ANSI SQL-92 语法重写它(即,使用 JOIN 和 ON 子句),它应该更清晰。

现在,所有 JOINWHERE 子句都混合在一起,因此不容易看出其中的关系。子查询不一定是问题;一旦语法清理完毕,这应该会变得更加清晰。

Rewrite it using ANSI SQL-92 syntax (i.e., using JOIN and ON clauses), and it should be much more clear.

Right now all of your JOIN and WHERE clauses are mixed together, so it is not easy to see the relationships. Subqueries are not necessarily a problem; this should become more clear once the syntax is cleaned up.

国产ˉ祖宗 2024-10-08 12:51:51

重写为使用 ANSI-92 SQL 并稍微简化以删除冗余连接,您的查询应如下所示:

SELECT o.order_id, 
       n.title, 
       c.first_name, 
       tdv6.name, 
       o.product_id,
       tdv5.tid,
       tdv8.name    month
FROM orders o
     join products p           on o.product_id = p.nid
     join node n               on p.nid = n.nid
     join customers c          on o.customer_email = c.customer_email
     join term_node tnv        on n.nid = tn.nid
     join term_data tdv6       on tn.tid = tdv6.tid AND tdv6.vid = 6
     left join term_data tdv5  on tn.tid = tdv5.tid AND tdv5.vid = 5
     left join term_data tdv8  on tn.tid = tdv8.tid AND tdv8.vid = 8

Rewritten to use ANSI-92 SQL and slightly simplified to remove redundant joins, your query should look something like this:

SELECT o.order_id, 
       n.title, 
       c.first_name, 
       tdv6.name, 
       o.product_id,
       tdv5.tid,
       tdv8.name    month
FROM orders o
     join products p           on o.product_id = p.nid
     join node n               on p.nid = n.nid
     join customers c          on o.customer_email = c.customer_email
     join term_node tnv        on n.nid = tn.nid
     join term_data tdv6       on tn.tid = tdv6.tid AND tdv6.vid = 6
     left join term_data tdv5  on tn.tid = tdv5.tid AND tdv5.vid = 5
     left join term_data tdv8  on tn.tid = tdv8.tid AND tdv8.vid = 8
胡渣熟男 2024-10-08 12:51:51

通常:

将您的 SELECT 列移至主 SELECT 语句,将 FROM 子句移至 JOIN原始 FROM 下方的 > 子句,以及该行的连接条件。您的 WHERE 子句可以保持原样。

另外,正如 @RedFilter 所说,使用 JOINON 子句。我认为你正在做笛卡尔,但由于语法我不确定。

例如(我不知道这对于您的表结构是否有效,因为您没有给出):

SELECT o.order_id, n.title, c.first_name, t1.name, o.product_id,ttd2.tid as 'tid', ttd4.name as 'name'
FROM orders o
INNER JOIN products p ON o.product_id = p.nid
INNER JOIN node n ON AND p.nid = n.nid
INNER JOIN customers c ON o.customer_email = c.customer_email
INNER JOIN term_data t1 ON t2.tid = t1.tid
INNER JOIN term_node t2 ON n.nid = t2.nid 
INNER JOIN ...
WHERE n.nid = t2.nid
AND ttd2.vid = 5 
AND ttn2.nid = p.nid 
AND ttd2.tid=ttn2.tid)
AND t1.vid = 6
AND ...

As a rule:

Move your SELECTed columns up to the main SELECT statement, move your FROM clause to a JOIN clause below the original FROM, and your join condition to that line as well. Your WHERE clause can stay as is.

Also as @RedFilter says, use JOIN and ON clauses. I think you are doing cartesians but I'm not sure due to the syntax.

For example (I don't know if this is valid for your table structure since you don't give it):

SELECT o.order_id, n.title, c.first_name, t1.name, o.product_id,ttd2.tid as 'tid', ttd4.name as 'name'
FROM orders o
INNER JOIN products p ON o.product_id = p.nid
INNER JOIN node n ON AND p.nid = n.nid
INNER JOIN customers c ON o.customer_email = c.customer_email
INNER JOIN term_data t1 ON t2.tid = t1.tid
INNER JOIN term_node t2 ON n.nid = t2.nid 
INNER JOIN ...
WHERE n.nid = t2.nid
AND ttd2.vid = 5 
AND ttn2.nid = p.nid 
AND ttd2.tid=ttn2.tid)
AND t1.vid = 6
AND ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文