我有一些麻烦将此查询重写为使用连接而不是两个子查询。如果你知道我的意思,我有一个解决它的问题。
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
你能帮忙吗?或者提供一些线索/提示。
答案 0 :(得分:4)
使用ANSI SQL-92语法重写它(即使用JOIN和ON子句),它应该更加清晰。
现在,您的所有JOIN
和WHERE
条款混合在一起,因此很难看到关系。子查询不一定是个问题;一旦语法被清理,这应该变得更加清晰。
答案 1 :(得分:2)
通常:
将SELECT
ed列移至主SELECT
语句,将FROM
子句移至原始JOIN
下方的FROM
子句,并将将条件连接到该行。您的WHERE
子句可以保持原样。
同样如@RedFilter所说,使用JOIN
和ON
条款。我认为你在做笛卡尔,但由于语法的原因,我不确定。
例如(我不知道这对你的表结构是否有效,因为你没有给它):
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 ...
答案 2 :(得分:2)
重写为使用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