Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
3个表上的MySql查询未返回所有行_Mysql_Subquery - Fatal编程技术网

3个表上的MySql查询未返回所有行

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

我有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_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;