Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL - Hàng đến cột

Tôi sẽ thêm phần giải thích dài hơn và chi tiết hơn về các bước cần thực hiện để giải quyết vấn đề này. Tôi xin lỗi nếu nó quá dài.

Tôi sẽ bắt đầu với cơ sở bạn đã đưa ra và sử dụng nó để xác định một vài thuật ngữ mà tôi sẽ sử dụng cho phần còn lại của bài đăng này. Đây sẽ là bảng cơ sở :

select * from history;

+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
|      1 | A        |        10 |
|      1 | B        |         3 |
|      2 | A        |         9 |
|      2 | C        |        40 |
+--------+----------+-----------+

Đây sẽ là mục tiêu của chúng tôi, bảng tổng hợp đẹp :

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

Các giá trị trong history.hostid cột sẽ trở thành giá trị y trong bảng tổng hợp. Các giá trị trong history.itemname cột sẽ trở thành giá trị x (vì những lý do rõ ràng).

Khi tôi phải giải quyết vấn đề tạo bảng tổng hợp, tôi sẽ giải quyết bằng quy trình ba bước (với bước thứ tư tùy chọn):

  1. chọn các cột quan tâm, tức là giá trị y giá trị x
  2. mở rộng bảng cơ sở với các cột bổ sung - một cột cho mỗi giá trị x
  3. nhóm và tổng hợp bảng mở rộng - một nhóm cho mỗi giá trị y
  4. (tùy chọn) chỉnh sửa bảng tổng hợp

Hãy áp dụng các bước sau cho vấn đề của bạn và xem những gì chúng tôi nhận được:

Bước 1:chọn các cột quan tâm . Trong kết quả mong muốn, hostid cung cấp giá trị y itemname cung cấp giá trị x .

Bước 2:mở rộng bảng cơ sở với các cột bổ sung . Chúng tôi thường cần một cột cho mỗi giá trị x. Nhớ lại rằng cột giá trị x của chúng ta là itemname :

create view history_extended as (
  select
    history.*,
    case when itemname = "A" then itemvalue end as A,
    case when itemname = "B" then itemvalue end as B,
    case when itemname = "C" then itemvalue end as C
  from history
);

select * from history_extended;

+--------+----------+-----------+------+------+------+
| hostid | itemname | itemvalue | A    | B    | C    |
+--------+----------+-----------+------+------+------+
|      1 | A        |        10 |   10 | NULL | NULL |
|      1 | B        |         3 | NULL |    3 | NULL |
|      2 | A        |         9 |    9 | NULL | NULL |
|      2 | C        |        40 | NULL | NULL |   40 |
+--------+----------+-----------+------+------+------+

Lưu ý rằng chúng tôi không thay đổi số hàng - chúng tôi chỉ thêm các cột bổ sung. Cũng lưu ý mẫu của NULL s - một hàng có itemname = "A" có giá trị khác rỗng cho cột mới A và giá trị null cho các cột mới khác.

Bước 3:nhóm và tổng hợp bảng mở rộng . Chúng ta cần group by hostid , vì nó cung cấp các giá trị y:

create view history_itemvalue_pivot as (
  select
    hostid,
    sum(A) as A,
    sum(B) as B,
    sum(C) as C
  from history_extended
  group by hostid
);

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 | NULL |
|      2 |    9 | NULL |   40 |
+--------+------+------+------+

(Lưu ý rằng chúng tôi hiện có một hàng cho mỗi giá trị y.) Được rồi, chúng ta sắp hoàn tất! Chúng ta chỉ cần loại bỏ những NULL xấu xí đó s.

Bước 4:kiểm tra trước . Chúng tôi sẽ thay thế bất kỳ giá trị null nào bằng các số 0 để tập hợp kết quả trông đẹp hơn:

create view history_itemvalue_pivot_pretty as (
  select 
    hostid, 
    coalesce(A, 0) as A, 
    coalesce(B, 0) as B, 
    coalesce(C, 0) as C 
  from history_itemvalue_pivot 
);

select * from history_itemvalue_pivot_pretty;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

Và chúng tôi đã hoàn thành - chúng tôi đã xây dựng một bảng tổng hợp đẹp mắt bằng cách sử dụng MySQL.

Những lưu ý khi áp dụng quy trình này:

  • giá trị nào để sử dụng trong các cột bổ sung. Tôi đã sử dụng itemvalue trong ví dụ này
  • giá trị "trung tính" nào để sử dụng trong các cột bổ sung. Tôi đã sử dụng NULL , nhưng nó cũng có thể là 0 hoặc "" , tùy thuộc vào tình huống chính xác của bạn
  • hàm tổng hợp nào sẽ sử dụng khi nhóm. Tôi đã sử dụng sum , nhưng countmax cũng thường được sử dụng (max thường được sử dụng khi xây dựng "đối tượng" một hàng được trải rộng trên nhiều hàng)
  • sử dụng nhiều cột cho các giá trị y. Giải pháp này không giới hạn ở việc sử dụng một cột duy nhất cho các giá trị y - chỉ cần cắm các cột bổ sung vào nhóm group by mệnh đề (và đừng quên select họ)

Các hạn chế đã biết:

  • giải pháp này không cho phép n cột trong bảng tổng hợp - mỗi cột tổng hợp cần được thêm theo cách thủ công khi mở rộng bảng cơ sở. Vì vậy, đối với 5 hoặc 10 giá trị x, giải pháp này là tốt. Đối với 100, không phải là tốt đẹp. Có một số giải pháp với các thủ tục được lưu trữ tạo ra một truy vấn, nhưng chúng xấu và khó làm đúng. Tôi hiện không biết cách hay để giải quyết vấn đề này khi bảng tổng hợp cần có nhiều cột.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách kết nối với MySQL bằng Node.js

  2. Viết hoa chữ cái đầu tiên. MySQL

  3. Kết nối Visual COBOL với MySQL

  4. Hướng dẫn SQL về khóa chính - Cách xác định khóa chính trong cơ sở dữ liệu

  5. Làm cách nào để xóa khỏi nhiều bảng trong MySQL?