我有这3个表mar_tb
,sel_tb
,cust_tb
。
mar_tb
mar_id (int) PK
mar_name (nvarchar(50)) not null
sel_tb
sel_id (int) pk
mar_id (int) (not null) FK
cust_tb
cust_id (int) pk
cust_active (bit) not null)
mar_id (int) (not null) FK
我在每张表中都有这些数据
mar_tb
mar_id | mar_name
-----------------
1 mar_one
2 mar_two
3 mar_three
sel_tb
sel_id | mar_id
----------------------------
1 1
2 1
cust_tb
cust_id | cust_active | mar_id
----------------------------
1 1 1
2 1 1
3 1 1
4 1 1
5 1 1
6 1 1
7 1 1
8 1 1
9 1 1
10 1 1
11 1 1
12 1 1
13 1 2
14 1 2
15 1 2
16 1 2
所有我需要得到这样的结果
mar_name | cus_num | sel_num
--------------------------------
mar_one 12 2
mar_three 0 0
mar_two 4 0
我试着编写像这样的简单代码
select
mar_tb.mar_name,
count(cust_tb.cust_id) as 'cus_num',
count(sel_tb.sel_id) over (PARTITION by mar_tb.mar_name ) as 'sel_num'
from
mar_tb
left join
cust_tb on cust_tb.mar_id = mar_tb.mar_id
left join
sel_tb on sel_tb.mar_id = mar_tb.mar_id
group by
mar_tb.mar_name, sel_tb.sel_id
我得到了这个结果
mar_name | cus_num | sel_num
--------------------------------
mar_one 12 2
mar_one 12 2
mar_three 0 0
mar_two 4 0
然后我通过使用像这样的子查询解决了这个问题
select
mar_name, cus_num, sel_num
from
(select
mar_tb.mar_name,
count(cust_tb.cust_id) as 'cus_num',
count(sel_tb.sel_id)over (PARTITION by mar_tb.mar_name ) as 'sel_num'
from
mar_tb
left join
cust_tb on cust_tb.mar_id = mar_tb.mar_id
left join
sel_tb on sel_tb.mar_id = mar_tb.mar_id
group by
mar_tb.mar_name, sel_tb.sel_id) a
group by
mar_name, sel_num, cus_num
最后我得到了我需要的东西
mar_name | cus_num | sel_num
--------------------------------
mar_one 12 2
mar_three 0 0
mar_two 4 0
问题是:有没有办法在不使用子查询或(不同)子句的情况下得到我需要的东西?
答案 0 :(得分:0)
如果我理解正确,我会使用union all
和group by
:
select m.mar_name, sum(cus_num) as cus_num, sum(sel_num) as sel_num
from mar_tb m left join
((select c.mar_id, 1 as cus_num, 0 as sel_num
from cust_tb c
) union all
(select s.mar_id, 0, 1
from sel_tb s
)
) cs
on m.mar_id = cs.mar_id
group by m.mar_name;
另一种方法使用apply
或相关子查询:
select m.mar_name, c.cus_num, s.sel_num
from mar_tb m outer apply
(select count(*) as cus_num
from cust_tb c
where c.mar_id = m.mar_id
) c outer apply
(select count(*) as sel_num
from sel_tb s
where s.mar_id = m.mar_id
) s;
这两个都使用子查询,但它们更直接地计算您想要的值。我强烈建议您更关心使用distinct
而不是使用子查询。
答案 1 :(得分:0)
如果我正确理解了您的问题,那么您可以尝试以下两种方式。
DECLARE @Mar_tb AS TABLE (mar_Id INT, mar_Name VARCHAR(100))
DECLARE @Sel_tb AS TABLE (sel_Id INT,Mar_Id INT)
DECLARE @cust_tb AS TABLE
(
cust_id int,
cust_active bit,
mar_id int)
INSERT INTO @mar_tb (mar_id ,mar_name)
VALUES
(1,'mar_one'),
(2,'mar_two'),
(3,'mar_three')
INSERT INTO @sel_tb(
sel_id ,mar_id)
VALUES(1 , 1),
(2 , 1),
(3 , 2)
INSERT INTO @cust_tb
(cust_id , cust_active , mar_id)
VALUES
( 1 , 1 , 1),
( 2 , 1 , 1),
( 3 , 1 , 1),
( 4 , 1 , 1),
( 5 , 1 , 1),
( 6 , 1 , 1),
( 7 , 1 , 1),
( 8 , 1 , 1),
( 9 , 1 , 1),
(10 , 1 , 1),
(11 , 1 , 1),
(12 , 1 , 1),
(13 , 1 , 2),
(14 , 1 , 2),
(15 , 1 , 2),
(16 , 1 , 2)
/*
mar_name | cus_num | sel_num
--------------------------------
mar_one 12 2
mar_three 0 0
mar_two 4 0 */
/************** Approach 1****/
SELECT m.mar_name,COUNT(DISTINCT s.sel_id) as sal, Count(DISTINCT c.cust_id) as customer
FROM @mar_tb m
LEFT OUTER JOIN @sel_tb s ON s.mar_id = m.mar_id
LEFT OUTER JOIN @cust_tb c ON c.mar_id = m.mar_id
GROUP BY m.mar_name
/************** Approach 2****/
SELECT m.mar_Name,COUNT(c.cust_Id) AS CustCount, tmp.saleCount
FROM @mar_tb m
LEFT OUTER JOIN @cust_tb c ON c.mar_id = m.mar_id
CROSS APPLY (SELECT COUNT(1) As saleCount
FROM @Sel_tb s
WHERE s.Mar_Id = m.mar_Id )tmp
GROUP BY m.mar_name,tmp.saleCount