2013-07-07 3 views
4

나는이 열이있는 테이블이 나타납니다 ID를 계산 player_in 필드에서와 같이 각각의 "player"의 반복 횟수를 세는 보고서를 만들기 위해 player_out 필드. 예를 들어, 테이블에이 두 행이있는 경우 (해당 순서대로).는 MySQL의 2 colums

id user_id player_in player_out 
1 1  88  56 
2 7  77  88 

플레이어 (88)에 대한 결과는 2 일, 선수 (56)와 77 단지 1

+0

+1 나는 그 사실을 알고 싶습니다. – ncm

+1

'SELECT COUNT (player_in), (SELECT COUNT (player_out) from myTable GROUP BY player_out) AS player_out from myTable GROUP BY player_in' work? –

+0

+1. 좋은 생각 이네. 나는 네가 똑똑하다고 생각해. – ncm

답변

3

를 사용하여 하나 개의 컬럼에 두 개의 열을 얻을 수 union all을 사용 하위 쿼리를 들어, 다음 표준을 사용합니다 count(*) :

참고 : 따라서이 질문에 대한 추가 요청마다 ins 및 outs에 대한 개별 합계가 쿼리에 포함되었습니다.

select 
    player_id, 
    count(*) as total, 
    sum(ins) as ins, 
    sum(outs) as outs 
from (
    select 
    player_in as player_id, 
    1 as ins, 
    0 as outs 
    from mytable 
    union all 
    select player_out, 0, 1 
    from mytable 
) x 
group by player_id 

참고 : union all하지 않는 반면에 당신이 union all (단지 union), union는 제거하기 때문에 중복을 사용해야합니다.

당신은 다음과 같이 다음 그룹 결과를 player_* 열을 피벗 해제하기 위해 2 행 가상 테이블 크로스 조인을 사용할 수
+0

잘 작동합니다. 여러 행이있는 테이블이 있는데이 행을 하나씩 조사 할 수는 없지만이 작업이 정상적으로 작동한다고 생각합니다. 검색어를 최적화 할 수있는 방법이 있습니까? – mauriblint

+0

player_in 및 player_out에 별도의 인덱스를 넣을 수 있습니다. 그 외에도 질의는 가능한 한 간단하게 잘 수행되어야합니다. – Bohemian

+0

한 번 더 질문합니다. 어떻게 각 플레이어에 대해 3 가지 항목, "ins" "outs"및 "total"을 얻을 수 있습니까? 고마워. – mauriblint

2

는 :

입니다
SELECT 
    player, 
    COUNT(*) AS total_count 
FROM (
    SELECT 
    CASE WHEN x.is_in THEN t.player_in ELSE t.player_out END AS player 
    FROM mytable t 
    CROSS JOIN (SELECT TRUE AS is_in UNION ALL SELECT FALSE) x 
) s 
GROUP BY 
    player 
;

, 원래 테이블의 모든 행은 본질적으로 파생 테이블의 is_in 열이 TRUE 또는 FALSE인지 여부에 따라 행의 각 복사본은 player_in 또는 player_out 중 하나를 제공하여 단일 player 열을 형성합니다. 이 방법은 UNION 메서드 suggested by @Bohemian보다 성능이 좋을 수 있습니다. (물리적 인) 테이블을 한 번만 전달하기 때문에 (그러나 특정 상황에서이 접근 방식에 상당한 이점이 있는지 확인하기 위해 두 방법을 테스트하고 비교해야합니다.).

SELECT 
    player, 
    COUNT( is_in OR NULL) AS in_count, COUNT(NOT is_in OR NULL) AS out_count, 
    COUNT(*)     AS total_count 
FROM (
    SELECT 
    x.is_in, 
    CASE WHEN x.is_in THEN t.player_in ELSE t.player_out END AS player 
    FROM mytable t 
    CROSS JOIN (SELECT TRUE AS is_in UNION ALL SELECT FALSE) x 
) s 
GROUP BY 
    player 
;

당신이 볼 수 있듯이, 파생 테이블 : 당신이 위에서 언급 한 대답에 귀하의 의견 중 하나에 요청대로

는이 같은 내 원래의 제안을 확장 할 수, 및 카운트에서 계산하려면 이제 추가로 is_in 열을 자체적으로 반환하고 열은 플레이어가 몇 번이나 들어 왔는지 계산하기 위해 두 조건부 집계에 사용됩니다. (만약 여러분이 관심이 있다면, OR NULL 트릭은 here을 설명한다.)

또한 SUM(condition)COUNT(condition OR NULL) 항목을 다시 작성할 수 있습니다. 그것은 확실히 두 표현을 단축 할 것이고, 일부는 또한 더 명확하고 더 우아한 카운트의 SUM 방법을 찾는다. 두 경우 모두 성능에 차이가 없으므로 취향에 맞는 방법을 선택하십시오.

두 번째 쿼리의 SQL Fiddle 데모는 here입니다.