2012-06-07 2 views
21

값과 다른 열을 동적 행 값을 선택하고 I는 구조 변경할 수 -MySQL의 (즉 활성 아직 사용), 컬럼 이름으로 I는 사용자 정보의 기존 테이블이

id name  value 
------------------------------ 
0  timezone Europe/London 
0  language en 
0  country 45 
0  something x 
1  timezone Europe/Paris 
1  language fr 
1  country 46 

시간대/언어/등 국가 이름의 예는, 그들이 변수가 될 수/해당 열의 행에서 고유 이외의 유한 목록이 없습니다

나는 반환 MySQL의 호환 SQL 쿼리 필요 -

id timezone  language country something 
--------------------------------------------------- 
0  Europe/London en   45  x 
1  Europe/Paris fr   46 

나는 MySQL에 Pivot 테이블 기능을 해킹하는 것과 관련된 stackoverflow에 대한 다양한 해답을 살펴 봤지만 같은 테이블의 열의 고유 한 행 값에서 가변 열 이름 별칭을 사용하는 경우와 일치하는 것으로 보이지는 않습니다. 나는 거의 잠을 자지 못했지만 모두 약간의 흐림이되기 시작했습니다. 미리 사과하십시오.

내가 찾을 수있는 가장 가까운이, 이름 열에서 가능한 모든/고유 값을받을 것이다 준비된 문 https://stackoverflow.com/a/986088/830171를 사용하고 CASE WHEN를 사용하는 쿼리를 작성하는 것입니다 및/또는 동일한 테이블 쿼리에 SELECT 또는 JOIN 하위 여러.

내가 생각할 수있는 대안은 해당 사용자 ID에 대한 모든 행을 가져 와서 for 루프에서 응용 프로그램 자체에서 처리하거나 한정된 양으로 이름을 제한하고 하위 사용 SELECT s/JOIN s. 그러나 두 번째 옵션은 새 이름이 추가 된 경우 이상하지 않습니다.이 쿼리를 다시 방문해야합니다.

말해 나는 디자인으로 이런 종류 의 동작을 선회에 대한 기본 지원을 (개발자가 아니라,이 프리젠 테이션에 더 적합의 느낌이없는 다른 RDBMS MySQL을 달리

+0

'sql'으로 표현하기 위해 정말로 이것을 필요로합니까, 아니면 선택한 프로그래밍 언어로 충분한 후 처리를 할 수 있습니까? 빈틈없는 데이터에 대해 조인해야하는 경우 뷰/proc가 트릭 일 수 있습니다. – bluevector

+0

예 지금 당장은 응용 프로그램 수준에서 혼란 스러울 것입니다. - 해당 사용자 ID에 대한 모든 행을 가져 와서 연관 배열에 데이터를 넣는 루프를 반복합니다. 난 그게 유일한 좋은 선택인지 확인하고 싶었어. 마이그레이션 및 일회성 보고서를위한 SQL 방법을 사용하는 것이 여전히 매우 편리합니다. – gingerCodeNinja

답변

39

분명 뭔가를 놓친하세요 데이터베이스, 응용 프로그램의 계층보다).

당신이 절대적으로 준비된 성명을 구축, MySQL은 이내에 조작을 perfom해야하는 경우는 아마 단지의 MySQL의 GROUP_CONCAT() 기능을 사용하는 것보다는 비록 CASE와 장난보다 —을 갈 수있는 방법입니다

SELECT CONCAT(
    'SELECT `table`.id', GROUP_CONCAT(' 
    , `t_', REPLACE(name, '`', '``'), '`.value 
     AS `', REPLACE(name, '`', '``'), '`' 
    SEPARATOR ''), 
' FROM `table` ', GROUP_CONCAT(' 
    LEFT JOIN `table` AS `t_', REPLACE(name, '`', '``'), '` 
      ON `table`.id = `t_', REPLACE(name, '`', '``'), '`.id 
      AND `t_', REPLACE(name, '`', '``'), '`.name = ', QUOTE(name) 
    SEPARATOR ''), 
' GROUP BY `table`.id' 
) INTO @qry FROM (SELECT DISTINCT name FROM `table`) t; 

PREPARE stmt FROM @qry; 
EXECUTE stmt; 

참조 그것에 sqlfiddle.

의 결과는 group_concat_max_len 변수 (기본값 : 1024 바이트 : 매우 긴 name 값을 제외하고는 여기에서 관련이 없을 것 같음)로 제한됩니다.

+4

와우 - 솔루션 작성 및 테스트를위한 모든 노력에 감사드립니다. 매우 감사. 저는 항상 이런 유형의 쿼리를 만드는 방법을 알고 싶었습니다. 그리고 상상했던 것처럼 복잡 해 보입니다. 당분간은 애플리케이션 수준의 복잡성을 피할 수 있지만이 쿼리는 여전히보고 및 마이그레이션에 매우 유용 할 것입니다. 감사. – gingerCodeNinja

+0

필자는 매우 유사한 시나리오를 가지고 있으며 훌륭한 예를 사용하여 피벗 된 결과를 올바르게 표시합니다.그러나 결과를 차트로 생성하고자 할 때 결과를 테이블에 저장해야합니다. 피벗 된 결과를 테이블에 저장할 수 있습니까? 또한, 위의 PHP에서 실행할 수 있습니까? 내 원본 테이블은 사용자, 날짜, 성능이며 피벗은 사용자가 행으로, 날짜가 열로, 성능이 셀 값으로 사용됩니다. – Sri

+0

예제 테이블을 sqlfiddle에 놓으십시오 (http://sqlfiddle.com/#!2/06be4/1 참조). – Sri