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

rắc rối với bảng tổng hợp mysql

Khi bạn đang cố gắng xoay giá trị động hoặc giá trị không xác định, tôi luôn khuyên bạn nên bắt đầu với phiên bản tĩnh hoặc mã hóa cứng của truy vấn trước, sau đó chuyển đổi nó thành SQL động.

MySQL không có hàm PIVOT nên bạn sẽ cần sử dụng hàm tổng hợp với biểu thức CASE để nhận kết quả. Phiên bản tĩnh của mã sẽ tương tự như sau:

select t.id teamid, 
  t.name teamname, 
  p.id processid, 
  p.name processname,
  max(case when pd.keyname = 'shape' then tpd.value end) shape,
  max(case when pd.keyname = 'vegetable' then tpd.value end) vegetable,
  max(case when pd.keyname = 'fruit' then tpd.value end) fruit,
  max(case when pd.keyname = 'animal' then tpd.value end) animal
from teams t
inner join teamprocesses tp
  on t.id = tp.teamid
inner join TeamProcessDetails tpd
  on tp.id = tpd.teamProcessId
inner join processes p
  on tp.processid = p.id
inner join processdetails pd
  on p.id = pd.processid
  and tpd.processDetailsid = pd.id
group by t.id, t.name, p.id, p.name;

Xem SQL Fiddle with Demo .

Bây giờ nếu bạn sắp có một số keynames không xác định mà bạn muốn chuyển đổi thành cột, thì bạn sẽ cần sử dụng tuyên bố đã chuẩn bị sẵn để tạo SQL động. Mã sẽ tương tự như:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when pd.keyname = ''',
      keyname,
      ''' then tpd.value end) AS ',
      replace(keyname, ' ', '')
    )
  ) INTO @sql
from ProcessDetails;

SET @sql 
    = CONCAT('SELECT t.id teamid, 
                t.name teamname, 
                p.id processid, 
                p.name processname, ', @sql, ' 
              from teams t
              inner join teamprocesses tp
                on t.id = tp.teamid
              inner join TeamProcessDetails tpd
                on tp.id = tpd.teamProcessId
              inner join processes p
                on tp.processid = p.id
              inner join processdetails pd
                on p.id = pd.processid
                and tpd.processDetailsid = pd.id
              group by t.id, t.name, p.id, p.name;');

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

Xem SQL Fiddle with Demo .

Một điều cần ghi nhớ GROUP_CONCAT hàm tạo chuỗi cột có độ dài tối đa mặc định là 1024, vì vậy nếu bạn có nhiều ký tự trong chuỗi này, bạn có thể phải thay đổi giá trị phiên cho group_concat_max_len .

Truy vấn này sẽ cho kết quả:

| TEAMID | TEAMNAME | PROCESSID | PROCESSNAME |  SHAPE | VEGETABLE |  FRUIT | ANIMAL |
|      1 |    teamA |         1 |    processA | circle |    carrot |  apple | (null) |
|      1 |    teamA |         2 |    processB | (null) |    (null) | (null) |    dog |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tôi có thể sử dụng cùng một ràng buộc khóa ngoại trong hai bảng khác nhau không?

  2. DataTable.Load hiển thị ít hàng hơn DataReader nguồn

  3. MYSQL - chọn 4 bản ghi đầu tiên cho mỗi danh mục trong bảng

  4. Mysql LEFT JOIN của ba bảng trả về nhiều Hàng

  5. Làm thế nào tôi có thể kiểm tra ngày gửi là giữa hai ngày trong cơ sở dữ liệu?