我正试图(比方说)收集客户报告。 在该报告中,我想要包括每个客户的订单总数和票号。
表:
Customer(id, name)
Order(id, customer_id, amount)
support_ticket(id, customer_id)
查询:
select
c.id as 'Customer',
count(distinct t.id) as "Ticket count",
count(distinct o.id) as "Order count",
sum(o.amount) as 'Order Amount'
from customer as c
inner join `order` as o on c.id = o.customer_id
inner join support_ticket as t on c.id = t.customer_id
group by c.id
由于我在两个表上加入了customer.id,因此我得到了所有可能的组合,因为我得到了所有可能的组合,所以如果客户端是多个票证,sum(o.amount)
我们会成倍增加“重复的行”
sqlFiddle(mysql):select 2
sqlFiddle(pg):http://sqlfiddle.com/#!9/ba39ba/13
这似乎是一个简单的案例,但我一直在考虑这个问题,我认为找不到报告的正确方法。
我做错了什么?
答案 0 :(得分:2)
您最好的选择是将订单表中的聚合重写为派生表;
EG
select
c.id as 'Customer',
count(distinct t.id) as "Ticket count",
o.amount as 'Order Amount' ,
o.[Order count]
from customer as c
inner join
(SELECT
o.customer_id,
sum(amount) as amount ,
count(distinct o.id) as "Order count"
from [order]
group by o.customer_id)
as o on c.id = o.customer_id
inner join support_ticket as t on c.id = t.customer_id
group by
c.id ,
o.amount ,
o.[Order count]
请注意,派生表列会添加到底部的group by子句中。
干杯!
答案 1 :(得分:2)
只需计算子查询中的order
值并加入即可。
SELECT
c.id as 'Customer'
,count(DISTINCT st.id) as 'Ticket Count'
,o.`Order Count`
,o.amount as `Order Amount`
FROM customer c
INNER JOIN support_ticket st
on c.id = st.customer_id
INNER JOIN (
SELECT
customer_id
,SUM(amount) as 'amount'
,count(distinct id) as 'Order Count'
FROM `order`
group by customer_id
) o
on c.id = o.customer_id
GROUP BY c.id;
答案 2 :(得分:1)
select c.id as 'Customer'
,t2.count_ticket as "Ticket count"
,t1.count_order as "Order count"
,t1.amount as 'Order Amount'
from customer as c
inner join (select customer_id
,count(id) as count_order
,sum(amount) as amount
from Order group by customer_id) t1
on c.id = t1.customer_id
inner join (select customer_id
,count(id) as count_ticket
from support_ticket group by customer_id) t2
on c.id = t2.customer_id
答案 3 :(得分:0)
在像你这样的情况下,当我认为我的问题的解决方案应该相当简单但我无法绕过它时,我倾向于使用WITH
子句。
不是因为它更好,而是因为它通过分解复杂性帮助我更好地理解我的代码。首先,我创建一个相对简单的临时。解决我问题的第一部分。
WITH temp AS (
SELECT
c.id AS "customer",
COUNT(DISTINCT o.id) AS "order_count",
SUM(o.amount) AS "order_amount"
FROM customer AS c
INNER JOIN "order" AS o on c.id = o.customer_id
GROUP BY c.id
)
然后我只是从temp中选择我的解决方案的前半部分,以这种方式添加所有中间结果,并解决我的初始sql的第二部分。
SELECT
temp.customer,
COUNT(DISTINCT t.id) as "ticket_count",
temp.order_count,
temp.order_amount
FROM temp
INNER JOIN support_ticket as t on temp.customer = t.customer_id
GROUP BY temp.customer, temp.order_count, temp.order_amount
原则与之前的所有答案相同,但SELECTS
是分开的,我可以快速检查它们,如果我对解决方案的某些部分感到满意,请继续。