MS SQL Server:自我和子查询的总数

时间:2018-10-02 08:53:59

标签: sql sql-server

假设我有以下表格:

表1:foo

id  should_be_counted (bit)
1   1
2   0
3   0
4   1

表2:条形图

id  foo_id  should_be_counted (bit)
1   1       0
2   1       1
3   2       1

如何查询数据,以便获得每个foo(其中foo.should_be_counted = 1)及其所有相关栏(其中bar.should_be_counted = 1)的总数。

预期结果:

id  count
1   2
2   1
3   0
4   1

样本数据(从Susang的答案中获取并更新):

DECLARE @foo AS TABLE(id INT, should_be_counted bit)
INSERT INTO @foo VALUES
(1,1),
(2,0),
(3,0),
(4,1)

DECLARE @bar AS TABLE(id INT, foo_id INT, should_be_counted bit)
INSERT INTO @bar VALUES
(1,1,0),
(2,1,1),
(3,2,1)

4 个答案:

答案 0 :(得分:3)

As I understand should_be_counted is always 1 or 0. Then this would be a simple and clear way:

select id, sum(cast(should_be_counted as int)) as cnt
from 
(
  select id, should_be_counted
  from foo 
  union all
  select foo_id, should_be_counted
  from bar 
) tmp
group by id;

DBFiddle Demo

Note: I later saw that it was bit, then would work as I said.

答案 1 :(得分:1)

我认为您只需要:

select f.id, case when b.cnt = 0 then f.should_be_counted else b.cnt end
from foo f outer apply
     ( select count(*) as cnt
       from bar b
       where b.foo_id = f.id
     ) b;

答案 2 :(得分:1)

Simple left join with group by wil get your desired output

DECLARE @foo AS TABLE(id INT, should_be_counted INT)
INSERT INTO @foo VALUES
(1,1),
(2,0),
(3,0),
(4,1)

DECLARE @bar AS TABLE(id INT, foo_id INT, should_be_counted INT)
INSERT INTO @bar VALUES
(1,1,0),
(2,1,1),
(3,2,1)

SELECT f.id, 
    COUNT(CASE WHEN f.should_be_counted>0 THEN 1 ELSE NULL END)+MAX(t.tot) AS [count]
FROM @foo f
OUTER APPLY(SELECT COUNT(*) tot 
            FROM @bar b WHERE b.foo_id = f.id AND b.should_be_counted > 0) t
GROUP BY f.id

OUTPUT:

id  count
1   2
2   1
3   0
4   1

答案 3 :(得分:0)

在我看来您需要加入并计数

   select f.id,coalesce((count(*),f.should_be_counted)) from foo f left join bar b on f.id=b.foo_id
    group by f.id