GROUP BY上的三个表连接不会产生正确的结果

时间:2016-07-22 03:00:25

标签: mysql join group-by

我有3张表。下面给出了一些样本数据的行动,来源和访问:

1。动作:

enter image description here

2。来源:

enter image description here

第3。访问:

enter image description here

现在,我们想知道每种来源类型的访问次数,而且还想分别通过联系和销售来检查访问次数。仍在使用的查询是:

Set rngPos = Range(Application.InputBox("Event Table will be size (" & UBound(arrayDest, 1) & _
", " & UBound(arrayDest, 2) & "). Choose the top left cell of desired location.", _
"Output Location", Type:=8).Address)

输出:

enter image description here

因此,如果您查看输出,那么您会发现访问次数完全等于每行的联系和销售总和。所以似乎没问题。但是,如果你总结所有行的所有访问,那么它不等于31.数字是47,这是不可能的,因为我们的访问表中只有31次访问。因此,输出数量不得超过访问表的访问量。这是我在查询中遇到的问题。如何提出必须符合原始表格的正确结果?

更新了表格操作:

enter image description here

1 个答案:

答案 0 :(得分:1)

这是因为您通过来源访问多人与多人的行动。理想情况下,您可以访问每个操作,但您也可以使用以下内容:

SELECT s.source_type AS source
, count(v.visits_id) as visits
, ifnull((SELECT SUM(a1.action_contact) FROM actions a1 WHERE s.source_id = a1.source_id and a1.action_contact=1 
and a1.action_date between "2016-07-01 00:00:00" and "2016-07-31 23:59:59" -- filters date
),0) as contacts
, ifnull((SELECT SUM(a2.action_sale) FROM actions a2 WHERE s.source_id = a2.source_id and a2.action_sale=1 and a2.action_date between "2016-07-01 00:00:00" and "2016-07-31 23:59:59"),0) as sales
, ifnull((SELECT SUM(a3.order_value) FROM actions a3 WHERE s.source_id = a3.source_id and a3.action_date between "2016-07-01 00:00:00" and "2016-07-31 23:59:59"),0) as sum_of_order_values
FROM visits v 
JOIN sources s ON v.source_id = s.source_id 
WHERE v.visitor_date between "2016-07-01 00:00:00" and "2016-07-31 23:59:59"
GROUP BY source 
ORDER BY visits DESC

这将为每个来源返回一条记录,访问次数按正常情况计算,但联系人和销售额总计为子查询,因此它们不会乘以具有相同来源的访问次数。如果您不熟悉多对多联接以及它们对记录数量(以及计数和求和函数)的影响,您可以在此处看到一些示例:http://www.phpknowhow.com/mysql/many-to-many-relationships/

编辑:我刚刚在sum_of_order_values上添加了第三个子查询,如果你的表很大,那么你的查询就会慢下来。根据评论的声音,您打算将visit_id添加到操作表中,一旦完成,您就可以将每个操作的联接作为一个不同的表并且只要您正确索引列,

就会大大提高您的查询效果

再次编辑:我刚刚将日期添加到WHERE条款中,只需要注意时区等。您可以设置"设置" session variables因此您可以一次更新所有内容,而不是单独更新。即添加

set @start_date = "2016-07-01 00:00:00";
set @end_date = "2016-07-31 23:59:59";

在查询开头,然后在and a3.action_date between @start_date and @end_date子句中使用WHERE