How to get multiple counts with one SQL query?

后端 未结 9 2024
清酒与你
清酒与你 2020-11-22 14:03

I am wondering how to write this query.

I know this actual syntax is bogus, but it will help you understand what I am wanting. I need it in this format, because it i

相关标签:
9条回答
  • 2020-11-22 14:27

    You can use a CASE statement with an aggregate function. This is basically the same thing as a PIVOT function in some RDBMS:

    SELECT distributor_id,
        count(*) AS total,
        sum(case when level = 'exec' then 1 else 0 end) AS ExecCount,
        sum(case when level = 'personal' then 1 else 0 end) AS PersonalCount
    FROM yourtable
    GROUP BY distributor_id
    
    0 讨论(0)
  • 2020-11-22 14:27

    Building on other posted answers.

    Both of these will produce the right values:

    select distributor_id,
        count(*) total,
        sum(case when level = 'exec' then 1 else 0 end) ExecCount,
        sum(case when level = 'personal' then 1 else 0 end) PersonalCount
    from yourtable
    group by distributor_id
    
    SELECT a.distributor_id,
              (SELECT COUNT(*) FROM myTable WHERE level='personal' and distributor_id = a.distributor_id) as PersonalCount,
              (SELECT COUNT(*) FROM myTable WHERE level='exec' and distributor_id = a.distributor_id) as ExecCount,
              (SELECT COUNT(*) FROM myTable WHERE distributor_id = a.distributor_id) as TotalCount
           FROM myTable a ; 
    

    However, the performance is quite different, which will obviously be more relevant as the quantity of data grows.

    I found that, assuming no indexes were defined on the table, the query using the SUMs would do a single table scan, while the query with the COUNTs would do multiple table scans.

    As an example, run the following script:

    IF OBJECT_ID (N't1', N'U') IS NOT NULL 
    drop table t1
    
    create table t1 (f1 int)
    
    
        insert into t1 values (1) 
        insert into t1 values (1) 
        insert into t1 values (2)
        insert into t1 values (2)
        insert into t1 values (2)
        insert into t1 values (3)
        insert into t1 values (3)
        insert into t1 values (3)
        insert into t1 values (3)
        insert into t1 values (4)
        insert into t1 values (4)
        insert into t1 values (4)
        insert into t1 values (4)
        insert into t1 values (4)
    
    
    SELECT SUM(CASE WHEN f1 = 1 THEN 1 else 0 end),
    SUM(CASE WHEN f1 = 2 THEN 1 else 0 end),
    SUM(CASE WHEN f1 = 3 THEN 1 else 0 end),
    SUM(CASE WHEN f1 = 4 THEN 1 else 0 end)
    from t1
    
    SELECT 
    (select COUNT(*) from t1 where f1 = 1),
    (select COUNT(*) from t1 where f1 = 2),
    (select COUNT(*) from t1 where f1 = 3),
    (select COUNT(*) from t1 where f1 = 4)
    

    Highlight the 2 SELECT statements and click on the Display Estimated Execution Plan icon. You will see that the first statement will do one table scan and the second will do 4. Obviously one table scan is better than 4.

    Adding a clustered index is also interesting. E.g.

    Create clustered index t1f1 on t1(f1);
    Update Statistics t1;
    

    The first SELECT above will do a single Clustered Index Scan. The second SELECT will do 4 Clustered Index Seeks, but they are still more expensive than a single Clustered Index Scan. I tried the same thing on a table with 8 million rows and the second SELECT was still a lot more expensive.

    0 讨论(0)
  • 2020-11-22 14:28

    I do something like this where I just give each table a string name to identify it in column A, and a count for column. Then I union them all so they stack. The result is pretty in my opinion - not sure how efficient it is compared to other options but it got me what I needed.

    select 'table1', count (*) from table1
    union select 'table2', count (*) from table2
    union select 'table3', count (*) from table3
    union select 'table4', count (*) from table4
    union select 'table5', count (*) from table5
    union select 'table6', count (*) from table6
    union select 'table7', count (*) from table7;
    

    Result:

    -------------------
    | String  | Count |
    -------------------
    | table1  | 123   |
    | table2  | 234   |
    | table3  | 345   |
    | table4  | 456   |
    | table5  | 567   |
    -------------------
    
    0 讨论(0)
提交回复
热议问题