2009-10-21 6 views
4

피벗 테이블 쿼리에서 작업하고 있습니다.행 데이터를 열로 동적으로 변환하는 mysql 쿼리

스노, 이름을 다음과 같이 스키마는 지구

같은 이름이 난 4 세트를 보는 바와 같이 예 예

1 Mike CA 
2 Mike CA 
3 Proctor JB 
4 Luke MN 
5 Luke MN 
6 Mike CA 
7 Mike LP 
8 Proctor MN 
9 Proctor JB 
10 Proctor MN 
11 Luke MN 

에 대한 샘플 데이터를 가지고 많은 지역에 나타날 수있다 (CA, JB, MN, LP). 지금은 지역

Name CA JB MN LP 
Mike 3 0 0 1 
Proctor 0 2 2 0 
Luke 0 0 3 0 

에 이름을 매핑하여 생성 피벗 테이블을 얻고 싶었다 나는 그러나 지구에서 증가 할 가능성이있는이

select name,sum(if(District="CA",1,0)) as "CA",sum(if(District="JB",1,0)) as "JB",sum(if(District="MN",1,0)) as "MN",sum(if(District="LP",1,0)) as "LP" from district_details group by name 

에 대해 다음 쿼리를 썼다 그 경우 나는 수동으로 쿼리를 편집하고 그것에 새로운 지구를 추가해야 할 것이다.

위의 쿼리를 동적으로 구별 할 수있는 쿼리가 있는지 알고 싶습니다. 프로 시저로 스크립트를 생성 할 수 있다는 것을 알고 있습니다. 다른 방법도 있습니까? 쿼리의 출력이 "district_details에서 별개의 (지역)을 선택 "때문에

내가 그렇게 물어 내가 열 전치 수 같은 것입니다 각 행에 나에게 하나의 컬럼을 갖는 지역 이름을 반환합니다.

+2

mysql의 GROUP_CONCAT() 함수를 살펴 보자. –

답변

3

가변 개수의 열을 반환하는 정적 SQL 문을 사용할 수 없습니다. 다른 지구의 수가 바뀔 때마다 그러한 성명서를 작성해야합니다. 이를 수행하려면 먼저 a를 실행하십시오.

SELECT DISTINCT District FROM district_details; 

자세한 내용이있는 지구 목록을 제공합니다. 그런 다음 이전 결과 (의사 코드)를 반복하는 SQL 문을 작성하십시오.

statement = "SELECT name " 

For each row returned in d = SELECT DISTINCT District FROM district_details 
    statement = statement & ", SUM(IF(District=""" & d.District & """,1 ,0)) AS """ & d.District & """" 

statement = statement & " FROM district_details GROUP BY name;" 

해당 쿼리를 실행하십시오. 그런 다음 가변 개수의 열 처리를 코드에서 처리해야합니다.

0

다음은 고유 한 (이름/지구) 쌍의 일치가 필요하다고 가정합니다. 나는. Luke/CA와 Duke/CA는 두 가지 결과를 산출합니다.

SELECT name, District, count(District) AS count 
FROM district_details 
GROUP BY District, name 

이 경우가 아니면 단순히 GROUP BY 절에서 이름을 제거하십시오.

마지막으로, 당신은 그룹화 된 모든 행을 계산하려고 노력하기보다는 값의 요약을 받고 나는이 수()에 대한 합() 전환 알 수 있습니다.

+0

귀하의 의견을 보내 주셔서 감사합니다, 그러나 그것은 내가 원하는 것이 아닙니다. 모든 지구의 모든 이름에 대해 지구 수를 표시하고 싶습니다. 따라서 루크 나 듀크의 경우 각 지구에 대한 점수를 얻고 싶습니다. 지구에 존재하지 않는다면 0입니다. 또한 합계 1 시간 (내가 쿼리에서하고있는)은 내가 믿는 똑같은 일을 할 것입니다. –

1

a) "For each"는 MySQL 저장 프로 시저에서 지원되지 않습니다. b) 저장 프로시 저는 이른바 동적 SQL 문을 사용하여 연결된 문자열에서 준비된 명령문을 실행할 수 없으며 두 개 이상의 별개 행이있는 결과를 반환 할 수 없습니다. c) 저장된 함수는 동적 SQL을 전혀 실행할 수 없습니다.

그것은 "... 왜 것 누군가 싶어"나는 당신이 당신의 해결책을 찾기를 바랍니다

당신은 좋은 생각이있어 모든 사람들이 그들이 생각하기 전에 정체를 폭로 것으로 보인다 번을 추적하는 악몽, 나는 아직도이다 내 검색.

1)에서 임시 테이블에 임시 테이블 2)로드 데이터를 생성 ... 기능을 구축> 저장 프로 시저 - 내가

(의사 코드를 변명)이었다 얻었다 종료 열을 if 문을 사용하여 3) 테이블 호출과 마찬가지로 저장 프로 시저의 INOUT 또는 OUT 매개 변수에 임시 테이블을로드하십시오. 하나 이상의 행을 반환 할 수있는 경우

또 다른 팁. .. 지구를 테이블 공동 창고로 보관하십시오. 모든 시스템에 대한 일반 텍스트가 될 수있는 쿼리 문자열을 동적으로 연결하기 위해 활성 상태로 표시된 구역을 반복하여 반복하고 반복하십시오.

다음을 사용하십시오.

@yourqyerstring에서 stmName을 준비하십시오. stmName을 실행하십시오. deallocate 준비 stmName;

(MySQL의 포럼의 저장 프로 시저 부분에 너무 훨씬 더 찾기)

어쩌면 그것은에서 쉽게 원래 시저에게

를 다시 설계 할 필요없이, 지역의 다른 세트마다 실행하기 숫자 형태. 테이블에서 일반 텍스트 콘텐츠로 작업하고 합계 나 계산 또는 합계를 사용하지 않습니다.

+0

"b) 저장 프로시 저는 이른바 동적 SQL 문을 사용하여 연결된 문자열에서 준비된 문을 실행할 수 없으며 두 개 이상의 고유 한 행이있는 결과를 반환 할 수 없습니다 c) 저장 함수는 동적 SQL을 전혀 실행할 수 없습니다. 그건 거짓입니다. MySQL의 저장 프로 시저는 동적 SQL을 실행할 수 있으며, 연결 및 준비가 가능하지만 중첩 될 수 없습니다 (즉, EXECUTE를 사용하여 다른 PREPARE/EXECUTE 문을 실행할 수 없음). 참조 : http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html –

+0

"a)"각각에 대해 "는 MySQL 저장 프로 시저에서 지원되지 않습니다." 사실이지만 REPEAT-UNTIL/LOOP와 함께 MySQL SP 내에서 루핑이 지원됩니다. 참조 : http://dev.mysql.com/doc/refman/5.0/en/repeat-statement.html –

+0

나는 위의 설명에도 불구하고 편향되어있다 : 나는 SP를 믿지 않으며 나는 비난한다. 그것의 사용. SP는 엄격하게 필요하지 않고 모든 다른 대안 (코드 + 캐싱과 같은)이 더 나쁜 것으로 입증되지 않는 한 악조건입니다. –

0

위의 @cballou에 대한 의견을 통해 OP가 요구하는 것과 정확히 일치하는 기능을 수행 할 수있었습니다 내 비슷한 상황 이니, 나중에 오는 사람들을 돕기 위해 여기에 추가하십시오.

일반 select 문 :

SELECT d.id ID, 
     q.field field, 
     q.quota quota 
    FROM defaults d 
    JOIN quotas q ON d.id=q.default_id 

수직 결과 :

ID field quota 
1 male 25 
1 female 25 
2 male 50 

Select 문 사용 GROUP_CONCAT : "필드"와 "의

SELECT d.id ID, 
     GROUP_CONCAT(q.fields SEPARATOR ",") fields, 
     GROUP_CONCAT(q.quotas SEPARATOR ",") quotas 
    FROM defaults d 
    JOIN quotas q ON d.id=q.default_id 

그럼 난 쉼표로 구분 얻을 필드 quotas "를 만들었으며 나중에 프로그래밍 방식으로 쉽게 처리 할 수 ​​있습니다.

수평 결과 :

ID fields  quotas 
1 male,female 25,25 
2 male  50 

매직!

관련 문제