2013-07-31 38 views
5

Tôi đã theo dõi một question tại đây để sử dụng truy vấn Mysql để tự động chuyển đổi hàng thành cột. Điều này hoạt động tốt, nhưng tôi cần phải chuyển đổi điều này dựa trên hai cột,Truy vấn Mysql để tự động chuyển đổi hàng thành cột trên cơ sở của hai cột

Truy vấn được đề cập trong liên kết ở trên hoạt động cho một cột "dữ liệu", nhưng tôi muốn làm việc cho hai cột là "dữ liệu" và " giá bán".

tôi đã thêm một ví dụ ở đây,

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

Table A 

| id|order|data|item|Price| 
-----+-----+---------------- 
| 1| 1| P| 1 | 50 | 
| 1| 1| P| 2 | 60 | 
| 1| 1| P| 3 | 70 | 
| 1| 2| Q| 1 | 50 | 
| 1| 2| Q| 2 | 60 | 
| 1| 2| Q| 3 | 70 | 
| 2| 1| P| 1 | 50 | 
| 2| 1| P| 2 | 60 | 
| 2| 1| P| 4 | 80 | 
| 2| 3| S| 1 | 50 | 
| 2| 3| S| 2 | 60 | 
| 2| 3| S| 4 | 80 | 

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

Result Table 

| id|order1|order2|order3|item1|item2|item3|item4| 
-----+-----+--------------------------------------- 
| 1| P | Q |  | 50 | 60 | 70 |  | 
| 2| P |  | S | 50 | 60 |  | 80 | 

tôi đã cố gắng tạo hai truy vấn khác nhau và sau đó tham gia để đạt được điều này, nhưng đó có thể không phải là một giải pháp tốt. Có thể bất kỳ một đề xuất một giải pháp giống như đã đề cập trong liên kết ở trên.

Cảm ơn

Trả lời

15

Nếu bạn đã có một số được biết đến các giá trị cho cả orderitem, sau đó bạn khó có thể mã truy vấn vào:

select id, 
    max(case when `order` = 1 then data end) order1, 
    max(case when `order` = 2 then data end) order2, 
    max(case when `order` = 3 then data end) order3, 
    max(case when item = 1 then price end) item1, 
    max(case when item = 2 then price end) item2, 
    max(case when item = 3 then price end) item3, 
    max(case when item = 4 then price end) item4 
from tableA 
group by id; 

Xem Demo. Nhưng một phần của vấn đề mà bạn sắp có là vì bạn đang cố chuyển đổi nhiều cột dữ liệu. Đề xuất của tôi để có được kết quả cuối cùng sẽ là hủy bỏ dữ liệu đầu tiên. MySQL không có chức năng bỏ ghim nhưng bạn có thể sử dụng UNION ALL để chuyển đổi nhiều cặp cột thành các hàng. Mã để bỏ khóa sẽ tương tự như sau:

select id, concat('order', `order`) col, data value 
from tableA 
union all 
select id, concat('item', item) col, price value 
from tableA; 

Xem Demo. Kết quả của việc này sẽ là:

| ID | COL | VALUE | 
----------------------- 
| 1 | order1 |  P | 
| 1 | order1 |  P | 
| 1 | order1 |  P | 
| 1 | item1 | 50 | 
| 1 | item2 | 60 | 
| 1 | item3 | 70 | 

Như bạn có thể thấy điều này đã đưa ra những nhiều cột của order/dataitem/price và chuyển đổi nó thành nhiều hàng. Khi đã hoàn tất, sau đó bạn có thể chuyển đổi các giá trị trở lại vào cột sử dụng một chức năng tổng hợp với một CASE:

select id, 
    max(case when col = 'order1' then value end) order1, 
    max(case when col = 'order2' then value end) order2, 
    max(case when col = 'order3' then value end) order3, 
    max(case when col = 'item1' then value end) item1, 
    max(case when col = 'item2' then value end) item2, 
    max(case when col = 'item3' then value end) item3 
from 
(
    select id, concat('order', `order`) col, data value 
    from tableA 
    union all 
    select id, concat('item', item) col, price value 
    from tableA 
) d 
group by id; 

Xem Demo. Cuối cùng, bạn cần phải chuyển đổi mã ở trên thành truy vấn báo cáo được chuẩn bị động:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when col = ''', 
     col, 
     ''' then value end) as `', 
     col, '`') 
) INTO @sql 
FROM 
(
    select concat('order', `order`) col 
    from tableA 
    union all 
    select concat('item', `item`) col 
    from tableA 
)d; 

SET @sql = CONCAT('SELECT id, ', @sql, ' 
        from 
        (
        select id, concat(''order'', `order`) col, data value 
        from tableA 
        union all 
        select id, concat(''item'', item) col, price value 
        from tableA 
       ) d 
        group by id'); 

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

Xem SQL Fiddle with demo. Điều này cho kết quả:

| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 | ITEM3 | ITEM4 | 
------------------------------------------------------------------- 
| 1 |  P |  Q | (null) | 50 | 60 |  70 | (null) | 
| 2 |  P | (null) |  S | 50 | 60 | (null) |  80 | 
Các vấn đề liên quan