Chỉ nhận tóm tắt tổng thể VỚI ROLLUP và GROUP BY cho nhiều trường


7

Thực hiện WITH ROLLUPkhi nhóm theo nhiều trường, MySQL trả về một hàng cuộn cho mỗi nhóm, cũng như tóm tắt chung:

CREATE TABLE test (name VARCHAR(50), number TINYINT);
INSERT INTO test VALUES
    ('foo', 1), ('foo', 1), ('foo', 2), ('foo', 3), ('foo', 3),
    ('bar', 1), ('bar', 2), ('bar', 2), ('bar', 2), ('bar', 3),
    ('baz', 1), ('baz', 2), ('bar', 2);
SELECT name, number, COUNT(1) FROM test GROUP BY name, number WITH ROLLUP;

+------+--------+----------+
| name | number | count(1) |
+------+--------+----------+
| bar  |      1 |        1 |
| bar  |      2 |        3 |
| bar  |      3 |        1 |
| bar  |   NULL |        5 |
| baz  |      1 |        1 |
| baz  |      2 |        2 |
| baz  |   NULL |        3 |
| foo  |      1 |        2 |
| foo  |      2 |        1 |
| foo  |      3 |        2 |
| foo  |   NULL |        5 |
| NULL |   NULL |       13 |
+------+--------+----------+

Tôi không được giới thiệu trong các bản giới thiệu cho foo / bar / baz, chỉ tóm tắt chung. Là gì hiệu quả nhất cách để đạt được điều này?


Câu trả lời:


3
SELECT * FROM
(
    SELECT name, number, COUNT(1) `count` FROM test
    GROUP BY name, number WITH ROLLUP
) A WHERE (ISNULL(name) + ISNULL(number)) <> 1;

hoặc là

SELECT * FROM
(
    SELECT name, number, COUNT(1) `count` FROM test
    GROUP BY name, number WITH ROLLUP
) A WHERE ISNULL(name) = ISNULL(number);

2

Nếu tất cả những gì bạn cần là tổng số, có thể hiệu quả hơn khi sử dụng union alltruy vấn như thế này:

select name, number, count(1) 
from test 
group by name, number 
union all 
select null, null, count(1) 
from test;

Nếu bạn có nhiều thuộc tính, WITH ROLLUPsẽ tạo ra nhiều tập con mà bạn sẽ bỏ đi trong phần chọn bên ngoài. Tôi không nghĩ trình tối ưu hóa MySQL sẽ nhận ra rằng nó có thể bỏ qua những thứ đó, nhưng đó chỉ là dự đoán.


1

Bạn cũng có thể thử HAVING:

SELECT name, number, COUNT(1) 
FROM test GROUP BY name, number 
WITH ROLLUP 
HAVING (number is not null or name is null);

hoặc là

HAVING (number is null) = (name is null)

0

Chắc chắn nếu bạn chỉ quan tâm đến bản tóm tắt tổng thể, bạn chỉ nên viết một truy vấn yêu cầu:

SELECT null, null, count(*) FROM test

(Bạn đã tạo một bảng thử nghiệm với 13 hàng, được nhóm trên mỗi cột bằng rollup và sau đó nói rằng bạn chỉ quan tâm đến hàng đó, một cách hiệu quả, đếm số lượng hàng trong bảng .. vì vậy chỉ cần làm điều đó)

Nếu bạn chỉ quan tâm đến các hàng chi tiết cộng với tóm tắt tổng thể, thì đó là bộ nhóm nào dành cho:

SELECT name, number, count(*) FROM test GROUP BY GROUPING SETS ((name, number), ())

Tập hợp trống sẽ đưa ra tóm tắt, tên + bộ số sẽ cung cấp chi tiết. ROLLUP tương đương với nhóm nhóm này:

((name, number), (name), ())

1
Đẹp nhưng MySQL không có GROUP BY GROUPING SETS.
ypercubeᵀᴹ

0

Trong trường hợp này, tóm tắt tổng thể bằng số lượng hồ sơ (tần số).

SELECT count(1) FROM test;

Nếu bạn quan tâm đến bản tóm tắt tổng thể của các con số thì

SELECT SUM(numbers) FROM test;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.