Tại sao chúng ta sử dụng Nhóm theo 1 và Nhóm bằng 1,2,3 trong truy vấn SQL?


26

Trong các truy vấn SQL, chúng tôi sử dụng nhóm theo mệnh đề để áp dụng các hàm tổng hợp.

  • Nhưng mục đích đằng sau việc sử dụng giá trị số thay vì tên cột với mệnh đề Nhóm là gì? Ví dụ: Nhóm theo 1.

3
order by 1Chỉ sử dụng khi ngồi tại mysql> dấu nhắc. Trong mã, sử dụng ORDER BY id ASC. Lưu ý trường hợp, tên trường rõ ràng và hướng đặt hàng rõ ràng.
dotancohen

Câu trả lời:


28

Đây thực sự là một điều tồi tệ khi làm IMHO và nó không được hỗ trợ trong hầu hết các nền tảng cơ sở dữ liệu khác.

Những lý do mọi người làm điều đó:

  • họ lười biếng - Tôi không biết tại sao mọi người nghĩ rằng năng suất của họ được cải thiện bằng cách viết mã ngắn gọn hơn là gõ thêm 40 mili giây để có được nhiều mã hơn.

Những lý do nó xấu:

  • đó không phải là tài liệu tự luận - ai đó sẽ phải phân tích danh sách CHỌN để tìm ra nhóm. Nó thực sự sẽ rõ ràng hơn một chút trong SQL Server, nó không hỗ trợ nhóm cao bồi, những người biết điều gì sẽ xảy ra như nhóm.

  • nó dễ vỡ - ai đó đến và thay đổi danh sách CHỌN vì người dùng doanh nghiệp muốn có đầu ra báo cáo khác và hiện tại đầu ra của bạn là một mớ hỗn độn. Nếu bạn đã sử dụng tên cột trong NHÓM THEO, thứ tự trong danh sách CHỌN sẽ không liên quan.

SQL Server hỗ trợ ĐẶT HÀNG B [NG [thứ tự]; Dưới đây là một số đối số song song chống lại việc sử dụng nó:


9

MySQL cho phép bạn thực hiện GROUP BYvới các bí danh ( Các vấn đề với Bí danh Cột ). Điều này sẽ tốt hơn nhiều khi làm GROUP BYvới số.

Google có nhiều ví dụ về việc sử dụng nó và tại sao nhiều người đã ngừng sử dụng nó.

Thành thật với bạn, tôi đã không sử dụng số cột trong ORDER BYGROUP BYtừ năm 1996 (lúc đó tôi đang thực hiện Phát triển PL / SQL của Oracle). Việc sử dụng số cột thực sự dành cho các bộ định thời cũ và khả năng tương thích ngược cho phép các nhà phát triển như vậy sử dụng MySQL và các RDBMS khác vẫn cho phép.


8

Xem xét trường hợp dưới đây:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Applications |         1 |
| 2016-05-31 | Apps         |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-05-31 | Videos       |         1 |
| 2016-06-01 | Apps         |         3 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Videos       |         2 |
| 2016-06-01 | Apps         |         2 |
+------------+--------------+-----------+

Bạn đã tìm ra số lượt tải xuống mỗi dịch vụ mỗi ngày, coi Ứng dụng và Ứng dụng là cùng một dịch vụ. Nhóm theo date, servicessẽ dẫn đến AppsApplicationsđược coi là dịch vụ riêng biệt.

Trong trường hợp đó, truy vấn sẽ là:

 select date, services, sum(downloads) as downloads
 from test.zvijay_test
 group by date,services

Và đầu ra:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Apps         |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Apps         |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Nhưng đây không phải là điều bạn muốn vì Ứng dụng và Ứng dụng được nhóm lại là yêu cầu. Vậy chúng ta có thể làm gì?

Một cách là thay thế Appsbằng Applicationscách sử dụng một CASEbiểu thức hoặc IFhàm và sau đó nhóm chúng qua các dịch vụ như:

select 
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test 
group by date,services

Nhưng điều này vẫn nhóm các dịch vụ xem xét AppsApplicationsnhư các dịch vụ khác nhau và cho cùng một đầu ra như trước đây:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Applications |         2 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         4 |
| 2016-06-01 | Applications |         5 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Nhóm trên một số cột cho phép bạn nhóm dữ liệu trên một cột bí danh.

select
  date,
  if(services='Apps','Applications',services) as services,
  sum(downloads) as downloads
from test.zvijay_test
group by date,2;

Và do đó cung cấp cho bạn đầu ra mong muốn như dưới đây:

+------------+--------------+-----------+
| date       | services     | downloads |
+------------+--------------+-----------+
| 2016-05-31 | Applications |         4 |
| 2016-05-31 | Videos       |         2 |
| 2016-06-01 | Applications |         9 |
| 2016-06-01 | Videos       |         2 |
+------------+--------------+-----------+

Tôi đã đọc nhiều lần rằng đây là một cách lười biếng để viết các truy vấn hoặc nhóm trên một cột bí danh không hoạt động trong MySQL, nhưng đây là cách nhóm các cột bí danh.

Đây không phải là cách viết truy vấn ưa thích, chỉ sử dụng nó khi bạn thực sự cần nhóm trên một cột bí danh.


" Nhưng điều này vẫn nhóm các dịch vụ coi Ứng dụng và Ứng dụng là các dịch vụ khác nhau và cho cùng một đầu ra như trước đây ". Điều này sẽ không được giải quyết nếu bạn chọn tên khác (không xung đột) cho bí danh?
Daddy32

3

Không có lý do hợp lệ để sử dụng nó. Nó chỉ đơn giản là một phím tắt lười biếng được thiết kế đặc biệt để gây khó khăn cho một số nhà phát triển khó tính trong việc tìm ra nhóm của bạn hoặc sắp xếp sau này hoặc cho phép mã bị lỗi một cách thảm hại khi ai đó thay đổi thứ tự cột. Hãy quan tâm đến các nhà phát triển đồng nghiệp của bạn và đừng làm điều đó.


0

Điều này được làm việc cho tôi. Mã nhóm các hàng lên đến 5 nhóm.

SELECT
USR.UID,
USR.PROFILENAME,
(
    CASE 
    WHEN MOD(@curRow, 5) = 0 AND @curRow > 0 THEN
        @curRow := 0
    ELSE
        @curRow := @curRow + 1 
        /*@curRow := 1*/ /*AND @curCode := USR.UID*/
    END
) AS sort_by_total  
FROM
    SS_USR_USERS USR,
    (
        SELECT
            @curRow := 0,
            @curCode := ''
    ) rt
ORDER BY
    USR.PROFILENAME,
    USR.UID

Kết quả sẽ như sau

nhập mô tả hình ảnh ở đây


0
SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2;

SELECT dep_month,dep_day_of_week,dep_date,COUNT(*) AS flight_count FROM flights GROUP BY 1,2,3;

Xem xét các truy vấn trên: Nhóm theo 1 có nghĩa là nhóm theo cột đầu tiên và nhóm theo 1,2 có nghĩa là nhóm theo cột thứ nhất và thứ hai và nhóm theo 1,2,3 có nghĩa là nhóm theo cột thứ hai và thứ ba. Ví dụ:

nhóm bằng 1,2

hình ảnh này cho thấy hai cột đầu tiên được nhóm theo 1,2 tức là nó không xem xét các giá trị khác nhau của dep_date để tìm số đếm (để tính tất cả các kết hợp khác nhau của hai cột đầu tiên được xem xét) trong khi truy vấn thứ hai cho kết quả này nhóm bằng 1,2,3

hình ảnh. Ở đây, nó đang xem xét tất cả ba cột đầu tiên và có các giá trị khác nhau để tìm số đếm tức là, nó được nhóm theo tất cả ba cột đầu tiên (để tính tất cả các kết hợp khác nhau của ba cột đầu tiên được xem xét).

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.