长时间用户,第一次发布海报。我发现了类似的问题/答案,通常涉及子查询,但我不确定如何应用于我的情况。
我有3张桌子:
table1
id
table2
id | val (each id has 1 of 3 possible values)
table3
id | val (each id has 1 of 3 possible values)
编辑:示例:( table1 =参加主题公园的每个人的唯一ID; table2 =每个访客首先访问的景点; table3 =每个访问者访问的第二个景点)。
我想写一个查询来查找7个不同的计数: (1)table1中唯一ID的计数 (2)table2中具有每个可能值的id的数量 (3)具有表3中每个可能值的id的数量
我的MySQL查询:
SELECT
count(DISTINCT table1.id) AS x1,
SUM(IF(table2.val='1'),1,0)) AS x2,
SUM(IF(table2.val='2'),1,0)) AS x3,
SUM(IF(table2.val='3'),1,0)) AS x4,
SUM(IF(table3.val='1'),1,0)) AS x5,
SUM(IF(table3.val='2'),1,0)) AS x6,
SUM(IF(table3.val='3'),1,0)) AS x7
FROM
table1
LEFT JOIN
table2 ON table1.id=table2.id
LEFT JOIN
table3 ON table1.id=table3.id
结果:
x1 =正确(因为DISTINCT)
x2,x3,x4 =正确
x5,x6,x7 =它们的数字应该是两倍(因为我得到的是笛卡尔积?)
有什么建议吗?
答案 0 :(得分:2)
您正在获得笛卡尔结果。由于您没有显示每个“ID”有多少“1”,“2”或“3”计数,因此只需从这些表中自行选择一个()。由于没有group by的总和将始终产生一条记录,因此您不需要任何连接,它将为每个摘要提取一条记录的结果,而不会产生笛卡尔结果。由于您的原始查询是LEFT JOIN到其他查询,因此表1上已存在该ID,因此为什么在每个子表中重新查询计数不同。
SELECT
SumForTable1.x1,
SumForTable2.x2,
SumForTable2.x3,
SumForTable2.x4,
SumForTable3.x5,
SumForTable3.x6,
SumForTable3.x7
FROM
( select count(DISTINCT table1.id) AS x1
from table1 ) SumForTable1,
( select SUM(IF(table2.val='1'), 1, 0)) AS x2,
SUM(IF(table2.val='2'), 1, 0)) AS x3,
SUM(IF(table2.val='3'), 1, 0)) AS x4
from table2 ) SumForTable2,
( select SUM(IF(table3.val='1'), 1, 0)) AS x5,
SUM(IF(table3.val='2'), 1, 0)) AS x6,
SUM(IF(table3.val='3'), 1, 0)) AS x7
from table3 ) SumForTable3
答案 1 :(得分:1)
我猜您的问题是table1
中的ID不是唯一的。因此即使它在table2/3
中是唯一的(根据您的描述),table2/3
中的每一行都会连接到table1
中的两行,因此会计算两次。与左连接无关,正常的内连接会有同样的问题。
如果mysql(我不太熟悉)可以让你像oracle那样进行内联视图,那么你可以通过编写查询来修复它:
SELECT
count(view1.id) AS x1,
SUM(IF(table2.val='1'),1,0)) AS x2,
SUM(IF(table2.val='2'),1,0)) AS x3,
SUM(IF(table2.val='3'),1,0)) AS x4,
SUM(IF(table3.val='1'),1,0)) AS x5,
SUM(IF(table3.val='2'),1,0)) AS x6,
SUM(IF(table3.val='3'),1,0)) AS x7
FROM
( SELECT DISTINCT table1.id
FROM table1
) view1
LEFT JOIN
table2 ON view1.id=table2.id
LEFT JOIN
table3 ON view1.id=table3.id
答案 2 :(得分:0)
我会在每张桌子上删除重复项:
SELECT
count(t1.id) AS t1,
SUM(IF(t2.val=1,1,0)) AS t21,
SUM(IF(t2.val=2,1,0)) AS t22,
SUM(IF(t2.val=3,1,0)) AS t23,
SUM(IF(t3.val=1,1,0)) AS t31,
SUM(IF(t3.val=2,1,0)) AS t32,
SUM(IF(t3.val=3,1,0)) AS t33
FROM (SELECT DISTINCT * FROM table1) as t1
JOIN (SELECT DISTINCT * FROM table2) as t2 ON t1.id=t2.id
JOIN (SELECT DISTINCT * FROM table3) as t3 ON t1.id=t3.id;