向MySQL表查询添加列
我有一个相对复杂的查询,其中包含一些子查询,我正在使用这些子查询为我的销售代表创建排行榜。问题是,主要数据是通过Sale_Date进行过滤的,而我需要其中一列通过Install_Date进行过滤,只有Installs列。我正在使用MySQL workbench和第三方商业智能平台以一种直观的方式输出数据。下面是一个简化的版本,我目前正在做的,但它显然不工作,或没有给我什么我想要的向MySQL表查询添加列,mysql,join,subquery,left-join,union,Mysql,Join,Subquery,Left Join,Union,我有一个相对复杂的查询,其中包含一些子查询,我正在使用这些子查询为我的销售代表创建排行榜。问题是,主要数据是通过Sale_Date进行过滤的,而我需要其中一列通过Install_Date进行过滤,只有Installs列。我正在使用MySQL workbench和第三方商业智能平台以一种直观的方式输出数据。下面是一个简化的版本,我目前正在做的,但它显然不工作,或没有给我什么我想要的 select `Rep`, `Sales`, `Passed Credit`, `Sales Scheduled`,
select `Rep`, `Sales`, `Passed Credit`, `Sales Scheduled`, Installs
from
(select Rep_Name as `Rep`, count(*) as `Sales`..., count(...) as `Sales Scheduled`
from ss.customers
left join ss.users
on customers.rep_id = users.id
where Sale_Date between curdate() - interval 6 day and curdate()
group by Rep_Name with rollup) cust,
(select Rep_Name, count(*) as `Installs`
from ss.customers
left join ss.installs
on customers.id = installs.id
left join ss.users
on customers.rep_id = users.id
where Install_Date between curdate() - interval 6 day and curdate()
group by Rep_Name) inst
order by `Sales` desc, `Passed Credit` desc, ..., `Installs` desc
我得到的输出对于第一个表cust中的所有字段都是正确的,但是我的所有代表都显示在查询的后半部分返回的第一次安装计数,无论是1还是20
它返回类似这样的内容:
Rep ----- Sales ----- Passed Credit ----- Sales Scheduled ----- Installs
John | 10 | 7 | 6 | 5
Mike | 8 | 7 | 6 | 5
Trey | 8 | 6 | 4 | 5
Drew | 6 | 3 | 3 | 5
Angel | 3 | 2 | 4 | 5
Total | 35 | 25 | 23 | 22
SELECT IFNULL(cust.`Rep_Name`,'Total') AS `Rep`
, cust.`Sales`
, cust.`Passed Credit`
, cust.`Sales Scheduled`
, inst.`Installs`
FROM ( SELECT cc.`Rep_Name` AS `Rep_Name`
, COUNT(cu.id) AS `Sales`
, ...
, COUNT(...) AS `Sales Scheduled`
FROM ss.customers cc
LEFT
JOIN ss.users cu
ON cu.`id` = cc.`rep_id`
AND cu.`Sale_Date` BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE()
GROUP BY cc.`Rep_Name`
WITH ROLLUP
) cust
LEFT
JOIN ( SELECT ic.`Rep_Name` AS `Rep_Name`
, COUNT(ii.id) AS `Installs`
FROM ss.customers ic
LEFT
JOIN ss.installs ii
ON ii.`id` = ic.`id`
AND ii.`Install_Date` BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE()
GROUP BY ic.`Rep_Name`
WITH ROLLUP
) inst
ON inst.`Rep_Name` <=> cust.`Rep_Name`
ORDER
BY cust.`Rep_Name` IS NOT NULL DESC
, cust.`Sales` DESC
, cust.`Passed Credit` DESC
, ...
, inst.`Installs` DESC
安装表也包括一些本周没有销售的人,但他们也没有出现在这里,他们应该出现在这里。理想情况下,这是表格的外观:
Rep ----- Sales ----- Passed Credit ----- Sales Scheduled ----- Installs
John | 10 | 7 | 6 | 5
Mike | 8 | 7 | 6 | 9
Trey | 8 | 6 | 4 | 4
Drew | 6 | 3 | 3 | 4
Angel | 3 | 2 | 4 | 0
Tracy | 0 | 0 | 0 | 3
Diego | 0 | 0 | 0 | 1
Total | 35 | 25 | 23 | 26
我尝试了一些连接、联合和where语句的疯狂组合。关于如何获得这一点,还有其他想法吗?感谢您的帮助
更新1
多亏了spencer7593,我通过使用左连接解决了安装列显示错误的问题。目前仍在显示本周销售为0的销售代表,但在前几周已安装了销售代表
我之前忘记包括的表的必要限定字段:
Customers - rep_id, Sale_Date, id, Passed_Credit, Sale_Scheduled
Users - id (which is customers.rep_id), Rep_Name, Rep_Office_Location
Installs - id (which is customers.id), Install_Date, Install_Status
我知道我们的CRM数据库一团糟,在不同的表上有多个同名的列代表不同的东西。我没有设计它,这是我目前必须面对的问题。您的查询产生了两个内联视图的笛卡尔乘积,cust和inst 我怀疑你想和Rep_名字上的匹配。用LEFT join关键字替换该逗号连接运算符,并添加一个ON子句以将cust.Rep与inst.Rep_名称匹配。既然您返回的是汇总,那么您可能希望将其与inst的总行相匹配 大多数列引用都是非限定的,所以我们无法分辨哪个表包含哪个列。代表姓名和销售日期是来自ss客户还是ss用户?我建议您对所有列引用进行限定,以帮助将来的读者,并避免在以后将列添加到表中时出现不明确的列错误 如果要返回所有Rep_Name,包括没有Sales的Rep_Name,那么如果Sale_Date是对users表中某列的引用,则可能需要将WHERE子句中的条件移动到ON子句中 猜测哪个表包含哪些列,并假设Rep_Name不为null,如下所示:
Rep ----- Sales ----- Passed Credit ----- Sales Scheduled ----- Installs
John | 10 | 7 | 6 | 5
Mike | 8 | 7 | 6 | 5
Trey | 8 | 6 | 4 | 5
Drew | 6 | 3 | 3 | 5
Angel | 3 | 2 | 4 | 5
Total | 35 | 25 | 23 | 22
SELECT IFNULL(cust.`Rep_Name`,'Total') AS `Rep`
, cust.`Sales`
, cust.`Passed Credit`
, cust.`Sales Scheduled`
, inst.`Installs`
FROM ( SELECT cc.`Rep_Name` AS `Rep_Name`
, COUNT(cu.id) AS `Sales`
, ...
, COUNT(...) AS `Sales Scheduled`
FROM ss.customers cc
LEFT
JOIN ss.users cu
ON cu.`id` = cc.`rep_id`
AND cu.`Sale_Date` BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE()
GROUP BY cc.`Rep_Name`
WITH ROLLUP
) cust
LEFT
JOIN ( SELECT ic.`Rep_Name` AS `Rep_Name`
, COUNT(ii.id) AS `Installs`
FROM ss.customers ic
LEFT
JOIN ss.installs ii
ON ii.`id` = ic.`id`
AND ii.`Install_Date` BETWEEN CURDATE() - INTERVAL 6 DAY AND CURDATE()
GROUP BY ic.`Rep_Name`
WITH ROLLUP
) inst
ON inst.`Rep_Name` <=> cust.`Rep_Name`
ORDER
BY cust.`Rep_Name` IS NOT NULL DESC
, cust.`Sales` DESC
, cust.`Passed Credit` DESC
, ...
, inst.`Installs` DESC
要获取所有销售代表以及任何匹配销售的列表,我们可以使用外部联接。注意,匹配的条件在外部联接的ON子句中,而不是WHERE子句中
对于在sales中并没有任何匹配行的销售代表,我们将从r返回一行和列。在这些行上,s中的列将为NULL
请注意,如果我们将s.sale_date上的谓词条件移动到WHERE子句,则会过滤掉s.sale_date为空值的所有行。这将否定连接的外部性,使其等同于内部连接。先生,您真是太棒了。我很抱歉没有将列限定在某些表中,并将猜测工作留给您。但实际上,你成功地把大部分的答案都答对了。当我有时间的时候,我会很快用这些信息更新我原来的帖子。左连接正是我所需要的。我仍在努力让本周销售额为0的销售代表在表中填写。由于sale_date不是ss.users中的参考列,因此目前正在尝试使用联合将它们添加到输出的底部。一旦我进一步了解这一点,我将更新您和帖子。要获得销售的零计数,请将驱动表设置为包含所有Rep_名称的表,并与包含相关销售的表进行左联接。并将销售日期的谓词条件放在ON子句中,而不是WHERE子句中。