복붙노트

[SQL] 어떻게 SQL 쿼리를 여러 수를 얻으려면?

SQL

어떻게 SQL 쿼리를 여러 수를 얻으려면?

나는이 쿼리를 작성하는 방법을 궁금해하고있다.

나는이 실제 구문은 가짜 알고,하지만 당신은 내가 걸려 이해하는 데 도움이됩니다. 그것은 훨씬 더 큰 쿼리의 일부이기 때문에,이 형식으로 필요합니다.

SELECT distributor_id, 
COUNT(*) AS TOTAL, 
COUNT(*) WHERE level = 'exec', 
COUNT(*) WHERE level = 'personal'

나는이 모든 하나 개의 쿼리에서 반환해야합니다.

하지 않습니다 작업을 다음 있도록 또한, 그것은 하나의 행에 있어야합니다 :

'SELECT distributor_id, COUNT(*)
GROUP BY distributor_id'

해결법

  1. ==============================

    1.당신은 집계 함수와 CASE 문을 사용할 수 있습니다. 이것은 기본적으로 어떤 RDBMS에서 PIVOT 기능과 같은 것입니다 :

    당신은 집계 함수와 CASE 문을 사용할 수 있습니다. 이것은 기본적으로 어떤 RDBMS에서 PIVOT 기능과 같은 것입니다 :

    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
    
  2. ==============================

    2.확실히 작동하는 한 가지 방법

    확실히 작동하는 한 가지 방법

    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 (SELECT DISTINCT distributor_id FROM myTable) a ;
    

    편집하다:  타린 ♦의 대답 @을 선택해야한다 대신 가능성이 방법을 사용하지 않는 이유에 대한 성능의 아래 KevinBalmforth의 휴식 @ 참조하십시오. 사람들이 자신의 옵션을 이해할 수 있도록 나는 이것을 떠날거야.

  3. ==============================

    3.

    SELECT 
        distributor_id, 
        COUNT(*) AS TOTAL, 
        COUNT(IF(level='exec',1,null)),
        COUNT(IF(level='personal',1,null))
    FROM sometable;
    

    COUNT는 null 이외의 값을 계산하고 DECODE은 조건이 충족되는 경우에만 null 이외의 값 1을 반환합니다.

  4. ==============================

    4.다른 게시 된 답변에 구축.

    다른 게시 된 답변에 구축.

    이 두 올바른 값을 생성합니다 :

    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 ; 
    

    그러나 성능은 분명히 데이터의 양이 증가함에 따라 더 관련이있을 것이다, 아주 다르다.

    내가 어떤 인덱스가 테이블에 정의되지 않았다 가정이 발견, 카운트와 쿼리가 여러 테이블 스캔을 할 것이라고하면서, 단일 테이블 스캔을 할 것 합계를 사용하여 쿼리.

    예를 들어, 다음 스크립트를 실행합니다 :

    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)
    

    2 SELECT 문을 선택하고 디스플레이 예상 실행 계획 아이콘을 클릭합니다. 당신은 첫 번째 문은 하나의 테이블 스캔을 할 것입니다 것을 볼 수 두 번째는 4. 분명히 하나의 테이블 스캔이 4보다 더 할 것입니다.

    클러스터 된 인덱스를 추가하면 흥미 롭다. 예를 들면

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

    먼저 하나의 클러스터 된 인덱스 스캔을 할 것입니다 위의 SELECT. 두 번째 SELECT는 클러스터 된 인덱스 찾는다 4 할 것입니다,하지만 그들은 여전히 ​​하나의 클러스터 된 인덱스 스캔보다 더 비싸다. 나는 800 만 개 행이 테이블에 같은 일을 시도하고 두 번째 SELECT는 여전히 훨씬 더 비쌌다.

  5. ==============================

    5.MySQL의 경우,이이 단축 될 수있다 :

    MySQL의 경우,이이 단축 될 수있다 :

    SELECT distributor_id,
        COUNT(*) total,
        SUM(level = 'exec') ExecCount,
        SUM(level = 'personal') PersonalCount
    FROM yourtable
    GROUP BY distributor_id
    
  6. ==============================

    6.모든 하나 개의 쿼리에 있어야하는 경우 글쎄, 당신은 노동 조합을 할 수있는 :

    모든 하나 개의 쿼리에 있어야하는 경우 글쎄, 당신은 노동 조합을 할 수있는 :

    SELECT distributor_id, COUNT() FROM ... UNION
    SELECT COUNT() AS EXEC_COUNT FROM ... WHERE level = 'exec' UNION
    SELECT COUNT(*) AS PERSONAL_COUNT FROM ... WHERE level = 'personal';
    

    또는, 처리 후 할 수있는 경우 :

    SELECT distributor_id, COUNT(*) FROM ... GROUP BY level;
    

    당신은 각 레벨의 수를 얻을 전체를 얻기 위해 그들 모두를 요약해야합니다.

  7. ==============================

    7.난 그냥 각 테이블을 열 A에서 그것을 식별하는 문자열 이름과 열의 수를 줄 경우 같은 것을 할. 그럼 조합 그들 모두 그들은 스택 있도록. 결과는 꽤 내 의견으로는 - 그것은 다른 옵션에 비해되지만 내가 필요한 걸 가지고하지 않도록하는 방법을 효율적입니다.

    난 그냥 각 테이블을 열 A에서 그것을 식별하는 문자열 이름과 열의 수를 줄 경우 같은 것을 할. 그럼 조합 그들 모두 그들은 스택 있도록. 결과는 꽤 내 의견으로는 - 그것은 다른 옵션에 비해되지만 내가 필요한 걸 가지고하지 않도록하는 방법을 효율적입니다.

    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;
    

    결과:

    -------------------
    | String  | Count |
    -------------------
    | table1  | 123   |
    | table2  | 234   |
    | table3  | 345   |
    | table4  | 456   |
    | table5  | 567   |
    -------------------
    
  8. ==============================

    8.OVER ()를 사용하여 추가 뉘앙스 Bluefeet의 허용 응답에 기반 :

    OVER ()를 사용하여 추가 뉘앙스 Bluefeet의 허용 응답에 기반 :

    SELECT distributor_id,
        COUNT(*) total,
        SUM(case when level = 'exec' then 1 else 0 end) OVER() ExecCount,
        SUM(case when level = 'personal' then 1 else 0 end) OVER () PersonalCount
    FROM yourtable
    GROUP BY distributor_id
    

    에서 아무것도 OVER ()를 사용하여 () 전체 데이터 세트에 대한 당신의 총 수를 줄 것이다.

  9. ==============================

    9.난 당신이 수를 선택이 또한 작동 할 수 있다고 생각 (*) ANC 등 (SELECT COUNT (*) 환자에서 어디 성 = 'F') patientF로, (환자에서 SELECT COUNT (*) 여기서 성 = 'M') 등 ANC에서 patientM

    난 당신이 수를 선택이 또한 작동 할 수 있다고 생각 (*) ANC 등 (SELECT COUNT (*) 환자에서 어디 성 = 'F') patientF로, (환자에서 SELECT COUNT (*) 여기서 성 = 'M') 등 ANC에서 patientM

    또한 당신은 patientF, (같은 SELECT COUNT (*) 환자의 경우 성 = ((*) 환자의 경우 Patient.Id = anc.PatientId 선택 카운트)를 선택하고 ANC 등이 SELECT COUNT (*) 등의 관련 테이블을 셀 수 ANC에서 patientM 같은 'M')

  10. from https://stackoverflow.com/questions/12789396/how-to-get-multiple-counts-with-one-sql-query by cc-by-sa and MIT license