2017-03-08 2 views
0

다음과 비슷한 형식의 데이터 (~ 70,000 행)가 있습니다. MySQL에서 여러 개의 열을 한 번에 요약

+--------+---------+---------+---------+-----+ 
| Number | A count | B count | C count | sum | 
+--------+---------+---------+---------+-----+ 
|  0 |  0 |  1 |  1 | 2 | 
|  2 |  0 |  1 |  2 | 3 | 
|  6 |  0 |  1 |  0 | 1 | 
|  9 |  0 |  0 |  1 | 1 | 
|  14 |  0 |  0 |  1 | 1 | 
|  18 |  1 |  0 |  0 | 1 | 
|  42 |  1 |  1 |  0 | 2 | 
|  69 |  1 |  0 |  0 | 1 | 
|  96 |  1 |  1 |  0 | 2 | 
| 514 |  1 |  0 |  0 | 1 | 
+--------+---------+---------+---------+-----+ 

(내 실제 사용에있을 것입니다 :

+-----------+-----+-----+----+-----------+ 
| ID  | A | B | C | Whatever | 
+-----------+-----+-----+----+-----------+ 
| 1banana | 42 | 0 | 2 | Um  | 
| fhqwhgads | 514 | 6 | 9 | Nevermind | 
| 2banana | 69 | 42 | 0 | NULL  | 
| pears  | 18 | 96 | 2 | 8.8  | 
| zubat2 | 96 | 2 | 14 | "NULL" | 
+-----------+-----+-----+----+-----------+ 

나는 각 번호가 같은 세 개의 열 중 발생 횟수를 계산하는 출력 테이블을 만들고 싶어 쿼리 결과보다 입력 테이블의 행 수가 10 배 이상 많음)

쿼리가 3 열의 아무 곳에도없는 숫자에 대해 0 행을 반환하는지 여부는 중요하지 않습니다. 별개의 합계 열의 부족 (내 기본 설정은 합계 열과 어떤 열에도없는 숫자는 제외됨).


현재, 나는 그룹 해제 된 데이터를 얻기 위해 다음 쿼리를 사용하고 있습니다 :

SELECT * #Number, COUNT(DISTINCT A), COUNT(DISTINCT B), COUNT(DISTINCT C) 
FROM 
    (# Generate a list of numbers to try 
    SELECT @ROW := @ROW + 1 AS `Number` 
    FROM DataTable t 
    join (SELECT @ROW := -9) t2 
    LIMIT 777 # None of the numbers I am interested in should be greater than this 
    ) AS NumberList 
INNER JOIN DataTable ON 
    Number = A 
    OR Number = B 
    OR Number = C 
    #WHERE <filters on DataTable columns to speed things up> 
#WHERE NUMBER = 10 # speed things up 
#GROUP BY Number 

가 반환 데이터와 유사한 테이블에 그대로 남아있는 코드의 주석 처리 된 부분과 위의 쿼리 테이블과 일치하지만 항목 수가 일치하는 경우 정렬됩니다. 동일한 Number으로 시작하는 모든 행을 그룹화하고 쿼리 결과의 "데이터"열의 값이 해당 열 Number의 발생 횟수 (DataTable)가됩니다.

내가 (그리고 SELECT 문에서 * 삭제) 그룹화 제표의 주석을 때, 나는 (원하는 출력의 sum 열 유용) 각 Number가 출연 얼마나 많은 행의 수를 얻을 수 있습니다. 그러나 Number이 각 데이터 열과 일치하는 횟수의 실제 합계는 나와 있지 않습니다. 단지 Number이 발견 된 행 수의 사본이 세 개인 경우입니다. 일치하는 총 행 수 대신 실제 열별로 그룹화를 얻으려면 어떻게합니까??


덧붙여 나는 과속에 관한 의견이있는 줄을 알고있을 것입니다. 이 쿼리는 입니다. 그래서 몇 가지 필터를 추가하여 테스트를 더 빠르게 실행합니다. 필자는 빠른 실행을위한 방법을 매우 좋아합니다. 전체 테이블의 쿼리 결과를 새 테이블로 보내는 것이이 데이터를 재사용 할 수있는 유일한 방법은 아닙니다. 성능이 좋지 않은 이유로 DataTable에있는 필터로 재생하십시오. 더 빠르게 실행되도록 전체 쿼리를 구성하는 더 좋은 방법이 있습니까?

답변

2

난 당신이 다음 집계를 union all 등을 사용하여 피벗 해제 할 생각 :

select number, sum(a) as a, sum(b) as b, sum(c) as c, count(*) as `sum` 
from ((select a as number, 1 as a, 0 as b, 0 as c from t 
    ) union all 
     (select b, 0 as a, 1 as b, 0 as c from t 
    ) union all 
     (select c, 0 as a, 0 as b, 1 as c from t 
    ) 
    ) abc 
group by number 
order by number; 
+0

이 아주 잘 작동! 3 번부터't'에서 필터링하는 것을 포 함할 컬럼을 포함시켜야 할 것처럼 보입니다. 그러나 그룹화와 정렬 바로 위의'WHERE' 필터를 사용할 수 있습니다. 유한하지만 알 수없는 수의 열에 대해이 작업을 수행하는 방법이 있습니까? 그렇지 않은 경우 (예 : 3-D) 비 -SQL DB가 이러한 상황에 처하게되면 훨씬 더 나은 도구가 될 것입니까? – cjm

관련 문제