加入未产生所需的结果
Join not producing results required
我想从 table PROD 中收集有关包含特定三元组值的行的所有详细信息。例如,我想获取具有列(ID,NBR AND COP_I)的行的所有数据,其值为(23534、99、0232)和(3423,5,09384)等
我想知道一种通过 Join select 三胞胎行的方法,这可能比我在下面做的方法更好,因为目前它不起作用。
以下查询生成所需的三元组,与前 100 行相关联:
SELECT ID, NBR, COP_I, SUM(PAD_MN) AS PAD_MN_SUMMED
FROM PROD
WHERE
PROD.FLAG = 0
GROUP BY 1,2,3
ORDER BY 4 DESC, 3,2,1
LIMIT 100 --TOP 100 ROWS
我尝试按如下方式加入上面的查询,以获取与前 100 行三元组对应的所有详细信息:
SELECT PROD.ID, PROD.NBR,PROD.COP_I,PROD.FLAG,PROD.TYPE,PROD.DATE, PROD.PAD_MN
FROM ( SELECT ID, NBR, COP_I, SUM(PAD_MN) AS PAD_MN_SUMMED
FROM PROD
WHERE
PROD.FLAG = 0
GROUP BY 1,2,3
ORDER BY 4 DESC, 3,2,1
LIMIT 100) TAB2
INNER JOIN PROD
ON (PROD.ID = TAB2.ID
AND PROD.NBR = TAB2.NBR
AND PROD.COP_I = TAB2.COP_I)
但是,上面的查询给出的行甚至没有与任何三元组相关联。 我觉得我可能在加入时犯了错误,但我不知道为什么以及如何纠正它。使用下面提供的答案时我遇到了类似的问题
更新
PROD Table 包含 10,000 多行看起来像:
ID NBR COP_I FLAG TYPE DATE PAD_MN
3423 5 09384 0 BA 14-06-2016 18657.43
546 1098 098 1 CFA 22-03-1998 2394566.92
3423 5 09384 0 AA 28-11-2013 3423534.12
23534 99 0232 0 BA 05-01-2016 7304567.12
需要结果,即仅包含前 100 行信息:
ID NBR COP_I FLAG TYPE DATE PAD_MN
23534 99 0232 0 BA 05-01-2016 17370567.09
3423 5 09384 0 AA 28-11-2013 6321009.98
但是,我的查询的输出给出了具有三元组 (ID、NBR、COP_I) 的行,这些行实际上并不是从上面产生所需三元组的第一个查询中输出的。
如果我理解正确的话,这就是你想要的
和join
select prod.* from (select id, nbr, cop_i, sum(pad_mn) as pad_mn_total from prod where prod.flag = 0 group by 1,2,3 order by 4 desc,3,2,1 limit 100) as top_prod left join prod using (id, nbr, cop_i);
没有join
select prod.* from (select id, nbr, cop_i, sum(pad_mn) as pad_mn_total from prod where prod.flag = 0 group by 1,2,3 order by 4 desc,3,2,1 limit 100) as top_prod, prod where prod.id = top_prod.id and prod.nbr = top_prod.nbr and prod.cop_i = top_prod.cop_i;
更好的方法是使用连接。在生产模式下使用查询之前,我强烈建议检查 explain
响应以了解 mysql 将如何收集数据以及索引如何针对每个查询工作。
在这里您可以找到一些关于 join
http://dev.mysql.com/doc/refman/5.7/en/join.html
的信息
如何使用 explain
此处描述 http://dev.mysql.com/doc/refman/5.7/en/using-explain.html
顺便说一句:阅读手册是解决问题的好方法
UPD:经过评论中的一些讨论:
问:有没有办法防止这些 "grouped" 行被恢复,同时仍然检索仅对 100 个排序行所需的其他信息?
答:select sum(pad_mn) as pad_mn_total, prod.* from prod where prod.flag = 0 group by id,nbr,cop_i order by 1 desc,cop_i,nbr,id limit 100
我想从 table PROD 中收集有关包含特定三元组值的行的所有详细信息。例如,我想获取具有列(ID,NBR AND COP_I)的行的所有数据,其值为(23534、99、0232)和(3423,5,09384)等
我想知道一种通过 Join select 三胞胎行的方法,这可能比我在下面做的方法更好,因为目前它不起作用。
以下查询生成所需的三元组,与前 100 行相关联:
SELECT ID, NBR, COP_I, SUM(PAD_MN) AS PAD_MN_SUMMED
FROM PROD
WHERE
PROD.FLAG = 0
GROUP BY 1,2,3
ORDER BY 4 DESC, 3,2,1
LIMIT 100 --TOP 100 ROWS
我尝试按如下方式加入上面的查询,以获取与前 100 行三元组对应的所有详细信息:
SELECT PROD.ID, PROD.NBR,PROD.COP_I,PROD.FLAG,PROD.TYPE,PROD.DATE, PROD.PAD_MN
FROM ( SELECT ID, NBR, COP_I, SUM(PAD_MN) AS PAD_MN_SUMMED
FROM PROD
WHERE
PROD.FLAG = 0
GROUP BY 1,2,3
ORDER BY 4 DESC, 3,2,1
LIMIT 100) TAB2
INNER JOIN PROD
ON (PROD.ID = TAB2.ID
AND PROD.NBR = TAB2.NBR
AND PROD.COP_I = TAB2.COP_I)
但是,上面的查询给出的行甚至没有与任何三元组相关联。 我觉得我可能在加入时犯了错误,但我不知道为什么以及如何纠正它。使用下面提供的答案时我遇到了类似的问题
更新
PROD Table 包含 10,000 多行看起来像:
ID NBR COP_I FLAG TYPE DATE PAD_MN
3423 5 09384 0 BA 14-06-2016 18657.43
546 1098 098 1 CFA 22-03-1998 2394566.92
3423 5 09384 0 AA 28-11-2013 3423534.12
23534 99 0232 0 BA 05-01-2016 7304567.12
需要结果,即仅包含前 100 行信息:
ID NBR COP_I FLAG TYPE DATE PAD_MN
23534 99 0232 0 BA 05-01-2016 17370567.09
3423 5 09384 0 AA 28-11-2013 6321009.98
但是,我的查询的输出给出了具有三元组 (ID、NBR、COP_I) 的行,这些行实际上并不是从上面产生所需三元组的第一个查询中输出的。
如果我理解正确的话,这就是你想要的
和join
select prod.* from (select id, nbr, cop_i, sum(pad_mn) as pad_mn_total from prod where prod.flag = 0 group by 1,2,3 order by 4 desc,3,2,1 limit 100) as top_prod left join prod using (id, nbr, cop_i);
没有join
select prod.* from (select id, nbr, cop_i, sum(pad_mn) as pad_mn_total from prod where prod.flag = 0 group by 1,2,3 order by 4 desc,3,2,1 limit 100) as top_prod, prod where prod.id = top_prod.id and prod.nbr = top_prod.nbr and prod.cop_i = top_prod.cop_i;
更好的方法是使用连接。在生产模式下使用查询之前,我强烈建议检查 explain
响应以了解 mysql 将如何收集数据以及索引如何针对每个查询工作。
在这里您可以找到一些关于 join
http://dev.mysql.com/doc/refman/5.7/en/join.html
如何使用 explain
此处描述 http://dev.mysql.com/doc/refman/5.7/en/using-explain.html
顺便说一句:阅读手册是解决问题的好方法
UPD:经过评论中的一些讨论:
问:有没有办法防止这些 "grouped" 行被恢复,同时仍然检索仅对 100 个排序行所需的其他信息?
答:select sum(pad_mn) as pad_mn_total, prod.* from prod where prod.flag = 0 group by id,nbr,cop_i order by 1 desc,cop_i,nbr,id limit 100