简体   繁体   English

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

[英]Rewriting SQL to JOINS instead of subqueries

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. 或提供一些线索/提示。

Rewrite it using ANSI SQL-92 syntax (ie, using JOIN and ON clauses), and it should be much more clear. 使用ANSI SQL-92语法(即,使用JOIN和ON子句)重写它,应该更加清楚。

Right now all of your JOIN and WHERE clauses are mixed together, so it is not easy to see the relationships. 现在,您所有的JOINWHERE子句都混合在一起,因此要查看它们之间的关系并不容易。 Subqueries are not necessarily a problem; 子查询不一定是问题。 this should become more clear once the syntax is cleaned up. 一旦语法清理干净,这应该变得更加清楚。

As a rule: 通常:

Move your SELECT ed 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. SELECT ed列移至主SELECT语句,将FROM子句移至原始FROM下方的JOIN子句,并将连接条件移至该行。 Your WHERE clause can stay as is. 您的WHERE子句可以保持原样。

Also as @RedFilter says, use JOIN and ON clauses. 就像@RedFilter所说的那样,请使用JOINON子句。 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 ...

Rewritten to use ANSI-92 SQL and slightly simplified to remove redundant joins, your query should look something like this: 重新编写为使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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