2013-02-12 46 views
30

MySQL có thể chuyển đổi cột thành hàng hay không, tự động thêm nhiều cột cần thiết cho các hàng. Tôi nghĩ câu hỏi của tôi có thể liên quan đến các bảng tổng hợp nhưng tôi không chắc chắn và tôi không biết cách đặt khung câu hỏi này ngoài cách khác bằng cách đưa ra ví dụ sau.Truy vấn Mysql để tự động chuyển đổi hàng thành cột

Cho một hai bảng A và B, mà trông giống như

Bảng A

+--+-----+----+ 
|id|order|data| 
+--+-----+----+ 
|1 |1 |P | 
+--+-----+----+ 
|2 |2 |Q | 
+--+-----+----+ 
|2 |1 |R | 
+--+-----+----+ 
|1 |2 |S | 
+--+-----+----+ 

Tôi muốn viết một truy vấn mà trông giống như sau:

Kết quả Bảng

+--+-----+-----+ 
|id|data1|data2| 
+--+-----+-----+ 
|1 |P |S | 
+--+-----+-----+ 
|2 |R |Q | 
+--+-----+-----+ 

Về cơ bản, tôi muốn chuyển mỗi hàng trong bảng B thành một cột trong bảng kết quả. Nếu có một mục mới được thêm vào bảng B cho id = 1, thì tôi muốn bảng kết quả tự động mở rộng bằng một cột để chứa điểm dữ liệu bổ sung này.

Trả lời

50

Bạn có thể sử dụng GROUP BYMAX để mô phỏng trục xoay. MySQL cũng hỗ trợ tuyên bố IF.

SELECT ID, 
     MAX(IF(`order` = 1, data, NULL)) data1, 
     MAX(IF(`order` = 2, data, NULL)) data2 
FROM TableA 
GROUP BY ID 

Nếu bạn có nhiều giá trị của order, SQL động có thể thích hợp hơn để bạn sẽ không cần phải sửa đổi các truy vấn:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'MAX(IF(`order` = ', `order`, ',data,NULL)) AS data', `order`) 
) INTO @sql 
FROM TableName; 

SET @sql = CONCAT('SELECT ID, ', @sql, ' 
        FROM TableName 
        GROUP BY ID'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

LƯỢNG SẢN XUẤT cả hai truy vấn:

╔════╦═══════╦═══════╗ 
║ ID ║ DATA1 ║ DATA2 ║ 
╠════╬═══════╬═══════╣ 
║ 1 ║ P  ║ S  ║ 
║ 2 ║ R  ║ Q  ║ 
╚════╩═══════╩═══════╝ 
+0

Tuyệt vời, ví dụ thứ hai chính xác là những gì tôi đã yêu cầu. Thật không may cho tôi có rất nhiều cú pháp SQL mới để có được đầu của tôi xung quanh. – Dom

+0

mà bạn có tiền tố '@' được gọi là biến người dùng. và tại đây, http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html, để tìm hiểu 'PreparedStatements'. –

+0

Các giải pháp trên là làm việc tuyệt vời nhưng kịch bản của tôi là thay vì áp dụng trục trên một cột trên cơ sở khác tôi cũng có một cột khác mà tôi muốn áp dụng trục trên cơ sở của cột khác. Nó giống như tôi áp dụng hai pivots riêng biệt trên hai cột của một bảng và tham gia có kết quả. Bất kỳ trợ giúp nào – Moon

5

Bạn cần phải sử dụng MAXGROUP BY để mô phỏng một PIVOT:

SELECT Id, 
    MAX(CASE WHEN Order = 1 THEN data END) data1, 
    MAX(CASE WHEN Order = 2 THEN data END) data2 
FROM TableA 
GROUP BY Id 

Và đây là SQL Fiddle.

+0

Điều này không hoạt động vì giới hạn của nó đối với hai cột và không thể xử lý động thêm cột bổ sung khi số lượng hoặc hàng tăng lên.Cảm ơn bạn đã thử mặc dù – Dom

+0

@Dom - không phải lo lắng - sql động là đặt cược tốt nhất của bạn nếu bạn không biết số lượng đơn đặt hàng tối đa. Nếu đó là 10, thì chỉ cần thêm 10 câu lệnh MAX :) - Rất vui vì chúng tôi có thể giúp đỡ. – sgeddes

+0

Downvoter, chăm sóc để giải thích? – sgeddes

Các vấn đề liên quan