3个表上的MySql查询未返回所有行
我有3个表格:问题、选项、注释到选项(选项注释)。 我想编写一个查询,在每行中返回以下值,并连接: 一个问题,所有选项,每个选项的所有评论 我的问题是:3个表上的MySql查询未返回所有行,mysql,subquery,Mysql,Subquery,我有3个表格:问题、选项、注释到选项(选项注释)。 我想编写一个查询,在每行中返回以下值,并连接: 一个问题,所有选项,每个选项的所有评论 我的问题是: select concat('{', '"qid":"', q.q_id, '", "qt":"', q.q_title, '", "op":[', group_concat('{"oi":"', o.op_id, '", "ot":"', o.opt_value, '", ', oc_list, '}' order by o.opt_up
select
concat('{', '"qid":"', q.q_id, '", "qt":"', q.q_title,
'", "op":[', group_concat('{"oi":"', o.op_id, '", "ot":"', o.opt_value, '", ', oc_list, '}'
order by o.opt_upvotes desc), ']}')
as r
from questions q, options o,
(select o.op_id as ocid, concat('"oc":[', group_concat('{"oci":"', oc.opt_com_id, '", "occ":"', oc.opt_com_value, '"}'
order by oc.opt_com_added_at), ']')
as oc_list
from options o, opt_comments oc
where oc.opt_com_to=o.op_id
group by o.op_id)
as r2
where o.op_id=r2.ocid
and q.q_id=o.option_to
group by q.q_id
order by q.q_added_at desc
limit 3;
但是上面的查询只提供那些至少有一条注释的选项。
我应该如何修改 您正在对以逗号分隔的表和子查询列表使用旧的联接语法。该语法是正确的,但会生成
内部联接
操作。此类联接将抑制与联接条件不匹配的行
您需要采用LEFT JOIN
语法。在不重构整个查询的情况下,我会说您应该进行更改
FROM a,
(select something from z) AS b
WHERE a.value=b.value
到
另外,请注意,您可能会在GROUP_CONCAT()
中遇到字符串长度限制。请阅读以下内容:
使用“左连接”。
例如:
使用“简单联接”时:
+------+------+------+--------+
|oid |名称| oid | com|
+------+------+------+--------+
|1 | opt1 | 1 | opt1 | U 1|
|1 | opt1 | 1 | opt1|U 2|
|3 | opt3 | 3 | opt3 | U 1|
+------+------+------+--------+
当“左连接”时:
+------+------+------+--------+
|oid |名称| oid | com|
+------+------+------+--------+
|1 | opt1 | 1 | opt1 | U 1|
|1 | opt1 | 1 | opt1|U 2|
|2 | opt2 |空|空|
|3 | opt3 | 3 | opt3 | U 1|
+------+------+------+--------+
为了跟进上述响应,SQL修改为使用外部联接:-
SELECT CONCAT('{', '"qid":"', q.q_id, '", "qt":"', q.q_title,'", "op":[', GROUP_CONCAT('{"oi":"', o.op_id, '", "ot":"', o.opt_value, '", ', oc_list, '}' ORDER BY o.opt_upvotes DESC), ']}') AS r
FROM options o
LEFT OUTER JOIN questions q
ON q.q_id = o.option_to
LEFT OUTER JOIN
(
SELECT o.op_id AS ocid,
CONCAT('"oc":[', GROUP_CONCAT('{"oci":"', oc.opt_com_id, '", "occ":"', oc.opt_com_value, '"}' ORDER BY oc.opt_com_added_at), ']') AS oc_list
FROM options o
INNER JOIN opt_comments oc
ON oc.opt_com_to=o.op_id
GROUP BY o.op_id
) r2
ON o.op_id = r2.ocid
GROUP BY q.q_id
ORDER BY q.q_added_at DESC
LIMIT 3;
看这个,我不确定子查询的连接。这看起来是带回一个编码的字符串,但是除了实际的连接之外,实际上没有使用这个子查询中的任何内容
因此,我不确定该子查询是否只是用于缩小返回的行的范围(在这种情况下,使用内部联接对其进行联接是合适的-您最好不要返回编码的字符串),或者您是否发布了您一直试图调试的查询的缩减版本。No,我没有剪切查询的任何部分,您的查询也只返回那些对其有注释的选项。我已修改了查询(将连接的问题保留为选项,而不是相反)。如果原始查询中没有遗漏任何内容,那么子查询似乎是多余的。
create table opt (oid int,name varchar(100));
insert into opt values (1,'opt1');
insert into opt values (2,'opt2');
insert into opt values (3,'opt3');
create table optcom (oid int,com varchar(100));
insert into optcom values (1,'opt1_1');
insert into optcom values (1,'opt1_2');
insert into optcom values (3,'opt3_1');
select opt.*,optcom.* from opt join optcom on opt.oid=optcom.oid;
select opt.*,optcom.* from opt left join optcom on opt.oid=optcom.oid;
SELECT CONCAT('{', '"qid":"', q.q_id, '", "qt":"', q.q_title,'", "op":[', GROUP_CONCAT('{"oi":"', o.op_id, '", "ot":"', o.opt_value, '", ', oc_list, '}' ORDER BY o.opt_upvotes DESC), ']}') AS r
FROM options o
LEFT OUTER JOIN questions q
ON q.q_id = o.option_to
LEFT OUTER JOIN
(
SELECT o.op_id AS ocid,
CONCAT('"oc":[', GROUP_CONCAT('{"oci":"', oc.opt_com_id, '", "occ":"', oc.opt_com_value, '"}' ORDER BY oc.opt_com_added_at), ']') AS oc_list
FROM options o
INNER JOIN opt_comments oc
ON oc.opt_com_to=o.op_id
GROUP BY o.op_id
) r2
ON o.op_id = r2.ocid
GROUP BY q.q_id
ORDER BY q.q_added_at DESC
LIMIT 3;