2013-02-26 42 views
5

giả định rằng tôi có một db có một cấu trúc ngang như thế này:cách tính giá trị ngang trên cơ sở dữ liệu?

ID | NAME | DATA1 | DATA2 | DATA3 | DATA4 | DATA5 | DATA6 | DATA7 
1 | mmm | 0 | 1 | 0 | 3 | 5 | 1 | 0 
2 | bbb | 0 | 0 | 0 | 1 | 0 | 1 | 1 

các thông tin là các trường dữ liệu và tôi muốn đếm tất cả các lần mà một biệt thức nhất định, chẳng hạn như "lớn hơn 0 "

cách tôi nghĩ rằng nó là vòng lặp trought tất cả các lĩnh vực, và đếm, hoặc COUNT() từng lĩnh vực DATA, vì vậy SUM() những 7 truy vấn ... ai có ý tưởng khác?

trong trường hợp này kết quả, vì vậy "count every DATA field with a value over 0" sẽ là = 7

+2

Bạn cần phải làm điều này tự động hoặc được các cột cố định? –

+0

tốt, cho phép giả định cột được cố định, vì vậy coulmn là từ DATA1 đến DATA7 thực sự là một giải pháp năng động nên được tốt đẹp. –

+1

trước tiên hãy chuẩn hóa dữ liệu của bạn – Strawberry

Trả lời

5

Không có built-in cú pháp mà sẽ cho phép bạn để đề cập đến một tập hợp các cột tự động, nghĩa là không phải đặt tên cho chúng một cách rõ ràng. Nếu bạn muốn động, bạn sẽ cần truy vấn siêu dữ liệu để lấy các tên cột bắt buộc, sau đó xây dựng truy vấn cuối cùng động.

Nhưng trước đó bạn vẫn cần có ý tưởng về chính xác truy vấn động sẽ tự động thực hiện công việc như thế nào. Vì vậy, trước tiên bạn cần phải giải quyết vấn đề trên một tập hợp hữu hạn.

Có nhiều cách để giải quyết vấn đề này. Các method suggested by @bluefeet có lẽ là một trong những rõ ràng hơn cũng như kém hiệu quả hơn. Bạn có thể thử ít nhất hai lựa chọn:

  1. Đếm mỗi cột riêng biệt sử dụng sự kết hợp có điều kiện và gắn lên tất cả các kết quả trong một biểu thức: (. Bí quyết OR NULL là giải thích here)

    SELECT 
        COUNT(DATA1 > 0 OR NULL) + 
        COUNT(DATA2 > 0 OR NULL) + 
        COUNT(DATA3 > 0 OR NULL) + 
        COUNT(DATA4 > 0 OR NULL) + 
        COUNT(DATA5 > 0 OR NULL) + 
        COUNT(DATA6 > 0 OR NULL) + 
        COUNT(DATA7 > 0 OR NULL) AS TOTAL 
    FROM yourtable 
    ; 
    

  2. Bỏ các cột DATA bằng cách sử dụng kết hợp chéo vào bảng ảo, sau đó áp dụng điều kiện cho cột chưa được bỏ phiếu:

    SELECT 
        COUNT(*) AS TOTAL 
    FROM (
        SELECT 
        CASE s.col 
         WHEN 'DATA1' THEN DATA1 
         WHEN 'DATA2' THEN DATA2 
         WHEN 'DATA3' THEN DATA3 
         WHEN 'DATA4' THEN DATA4 
         WHEN 'DATA5' THEN DATA5 
         WHEN 'DATA6' THEN DATA6 
         WHEN 'DATA7' THEN DATA7 
        END AS DATA 
        FROM yourtable 
        CROSS JOIN (
        SELECT 'DATA1' AS col 
        UNION ALL SELECT 'DATA2' 
        UNION ALL SELECT 'DATA3' 
        UNION ALL SELECT 'DATA4' 
        UNION ALL SELECT 'DATA5' 
        UNION ALL SELECT 'DATA6' 
        UNION ALL SELECT 'DATA7' 
    ) s 
    ) s 
    WHERE DATA > 0 
    ; 
    

    (Trong một cách, điều này cũng tương tự như đề nghị @ bluefeet, nó chỉ không sử dụng bất kỳ công đoàn.)

+0

rất thanh lịch và được giải thích rõ ràng, cảm ơn rất nhiều, thủ thuật OR NULL thực sự tốt đẹp! –

3

Kể từ khi dữ liệu của bạn không được bình thường bạn nên UNPIVOT các dữ liệu để có được kết quả. MySQL không có chức năng bỏ ghim để bạn có thể sử dụng truy vấn UNION ALL để chuyển đổi các cột thành các hàng. Khi dữ liệu nằm trong các hàng, bạn có thể dễ dàng đếm số lượng giá trị. Tôi sẽ sử dụng một cái gì đó tương tự như sau:

select count(*) total 
from 
(
    select id, name, 'data1' col, data1 as value 
    from yourtable 
    union all 
    select id, name, 'data2' col, data2 as value 
    from yourtable 
    union all 
    select id, name, 'data3' col, data3 as value 
    from yourtable 
    union all 
    select id, name, 'data4' col, data4 as value 
    from yourtable 
    union all 
    select id, name, 'data5' col, data5 as value 
    from yourtable 
    union all 
    select id, name, 'data6' col, data6 as value 
    from yourtable 
    union all 
    select id, name, 'data7' col, data7 as value 
    from yourtable 
) src 
where value > 0 

Xem SQL Fiddle with Demo

+0

công đoàn tất cả - những gì về hiệu suất? – VAV

+0

@VAV 'UNION ALL' hoạt động tốt hơn' UNION' vì nó không xóa bất kỳ bản ghi trùng lặp nào. – Taryn

+1

có, và không thực hiện bất kỳ "phân loại" nhưng câu hỏi của tôi về 7 lần 'union' và tập hợp kết quả tập hợp dữ liệu cho các bảng lớn - đó có phải là giải pháp sản xuất không? – VAV