Giáo sư của tôi đã dạy tôi rằng `COUNT` không tính các bản sao


40

Tại trường đại học, giáo sư của tôi đã dạy tôi năm nay rằng câu lệnh SQL này:

SELECT COUNT(length) FROM product

sẽ trở lại 2với tập dữ liệu sau:

|   product         |
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |    40  | A31  |

Cô biện minh cho điều đó bằng cách nói rằng COUNTkhông tính các bản sao.

Tôi nói với giáo sư của tôi rằng tôi nghĩ rằng cô ấy đã làm cho một lỗi. Cô ấy trả lời tôi rằng một số DBMS có thể hoặc không thể tính các bản sao.

Sau khi thử rất nhiều DBMS, tôi chưa bao giờ tìm thấy cái nào có hành vi này.

DBMS này có tồn tại không?

Có bất kỳ lý do cho một giáo sư để dạy hành vi này? Và thậm chí không đề cập đến việc DBMS khác có thể hành xử khác đi?


FYI, hỗ trợ khóa học có sẵn ở đây (bằng tiếng Pháp) . Slide liên quan nằm ở góc dưới bên trái ở trang 10.


1
Vì các slide nói về ANSi SQL, giáo sư của bạn đã sai, ngay cả trong tiêu chuẩn năm 1992 (xem trang 125 ở đây contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt ) liệt kê các hành vi khác nhau để đếm và không có DISTINCT. Bạn có thể muốn ghé thăm thư viện với phiên bản cập nhật (bao gồm nhiều tùy chọn hơn như TẤT CẢ / QUÁ)
eckes

Câu trả lời:


38

COUNT không tính các bản sao trong tất cả các DBMS mà tôi biết, nhưng.

Có lý do nào để giáo sư dạy hành vi này không

Vâng, có một lý do. Trong lý thuyết quan hệ ban đầu (làm nền tảng cho tất cả DBMSes quan hệ hiện đại) mối quan hệ là một bộ theo nghĩa toán học của từ này. Điều đó có nghĩa là không có mối quan hệ nào có thể chứa các bản sao cả, bao gồm tất cả các mối quan hệ chuyển tiếp, không chỉ các bảng của bạn.

Theo nguyên tắc này, bạn có thể nói rằng SELECT length FROM productchỉ chứa hai hàng, do đó COUNTtrả về tương ứng 2, không 3.


Ví dụ: trong Rel DBMS, sử dụng mối quan hệ được đưa ra trong câu hỏi và cú pháp Hướng dẫn D :

SUMMARIZE product {length} BY {}: {c := COUNT()}

cho:

Kết quả tương đối


1
Vì chúng tôi đã có các khóa học lý thuyết quan hệ với giáo sư này vào cuối năm nay, tôi nghĩ đây là câu trả lời đúng. Dù sao, tôi sẽ hỏi giáo sư của tôi để biết thêm thông tin.
Jules Lamur

2
Giáo viên có thể đã nói về DBMS nói chung, không chỉ về các DBMS SQL. Như bản chỉnh sửa cho thấy, có các triển khai của mô hình quan hệ (ví dụ Rel), trong đó COUNThoạt động khác với triển khai SQL.
ypercubeᵀᴹ

47

Giáo sư của bạn đã phạm sai lầm hoặc bạn hiểu sai những gì cô ấy nói. Trong ngữ cảnh của các DBMS quan hệ, được triển khai bởi các nhà cung cấp khác nhau, hàm tổng hợp COUNT(<expression>)trả về số lượng giá trị không phải NULL <expression>trong tập kết quả (hoặc một nhóm).

Có một trường hợp đặc biệt COUNT(*), trả về số lượng hàng trong tập kết quả hoặc nhóm, không phải số lượng giá trị của bất cứ thứ gì. Điều này tương đương với COUNT(<constant expression>), chẳng hạn như COUNT(1).

Nhiều cơ sở dữ liệu hỗ trợ COUNT(DISTINCT <expression>), sẽ trả về số lượng giá trị duy nhất của <expression>.


13

Nếu giáo sư của bạn đang nói về SQL, tuyên bố đó là sai. COUNT(x)sẽ trả về số lượng hàng trong đó x IS NOT NULLbao gồm các mục trùng lặp. COUNT(*) or COUNT([constant])là một trường hợp đặc biệt sẽ đếm các hàng, ngay cả những hàng có mỗi cột NULL. Tuy nhiên, các bản sao luôn được tính, trừ khi bạn chỉ định COUNT(distinct x). Thí dụ:

with t(x,y) as ( values (null,null),(null,1),(1,null),(1,1) )

select count(*) from t
4

select count(1) from t
4

select count(distinct 1) from t
1

select count(x) from t
2

select count(distinct x) from t
1

COUNT(distinct *) không hợp lệ AFAIK.

Là một lưu ý phụ, NULL giới thiệu một số hành vi không trực quan. Ví dụ:

SELECT SUM(x) + SUM(y),  SUM(x + y) FROM T
4, 2

I E:

SUM(x)+SUM(y) <> SUM(x+y)

Nếu anh ấy / cô ấy đang nói về một hệ thống quan hệ như được mô tả bởi, ví dụ, cuốn sách Cơ sở dữ liệu, Loại và Mô hình quan hệ: Tuyên ngôn thứ ba của CJ Date và Hugh Darwen - đó sẽ là một tuyên bố chính xác.

Nói rằng chúng tôi có mối quan hệ:

STUDENTS = Relation(["StudentId", "Name"]
                    , [{"StudentId":'S1', "Name":'Anne'},
                       {"StudentId":'S2', "Name":'Anne'},
                       {"StudentId":'S3', "Name":'Cindy'},
                     ])
SELECT COUNT(NAME) FROM STUDENTS

tương ứng với:

COUNT(STUDENTS.project(['Name']))

I E

COUNT( Relation(["Name"]
               , [{"Name":'Anne'},
                  {"Name":'Cindy'},
                ]) )

mà sẽ trả lại 2 .


3

Đây là cách nó hoạt động trong MS SQL Server

COUNT (*) trả về số lượng vật phẩm trong một nhóm. Điều này bao gồm các giá trị NULL và trùng lặp.

COUNT (TẤT CẢ biểu thức) đánh giá biểu thức cho mỗi hàng trong một nhóm và trả về số lượng giá trị không có giá trị.

COUNT (biểu thức DISTINCT) đánh giá biểu thức cho mỗi hàng trong một nhóm và trả về số lượng giá trị duy nhất, không có giá trị.


1

Nếu cái bàn trông như thế này,

|   product         |
|id | length | code |
|-------------------|
| 1 |    11  | X00  |
| 2 |    11  | C02  |
| 3 |  null  | A31  |

bạn có thể mong đợi truy vấn trả về 2, ít nhất là trong Oracle DB, vì null không được tính. Các bản sao được tính tốt.


-7

có lẽ cô ấy có nghĩa là kết hợp với độc nhất, nhưng Count làm TỪNG DUPLICATE. Có một số giáo viên không biết nội dung của họ, không phải lo lắng chỉ thông báo cho bạn cùng lớp / bạn bè của bạn để khi họ tiếp tục với db cao hơn và cuộc sống thực họ sẽ không quên, tốt hơn là gửi một tin nhắn nặc danh cho giáo viên của bạn hỏi họ rằng họ đã không hiểu một số hàm sql và muốn trình diễn, yêu cầu giáo viên của bạn đưa ra cách để lớp gợi ý những gì cần chèn bao gồm các bản sao (không có dữ liệu lớn) và khi cô ấy sử dụng số đếm hàm, bạn đã nhận được cô ấy. Một số người sẽ chọn nó, Ngoài ra khi cô ấy nói các cơ sở dữ liệu khác, bạn của bạn sẽ hỏi cô ấy những cơ sở dữ liệu nào, sau đó nhân đôi cô ấy và nói rằng bạn đã thử tất cả các cơ sở dữ liệu đó và chúng không hoạt động như cô ấy nói và điều đó đã thu thập các bản sao.


2
Tôi không chắc là tôi sẽ cố tình đối kháng với giáo viên. Với một số người, có thể hoàn toàn thích hợp khi chỉ gặp riêng họ và hỏi về điều đó, với ví dụ bạn đã sẵn sàng (chỉ để cho thấy rằng bạn có lý do để hỏi). Tuy nhiên, những điều cơ bản của phương pháp này là hợp lệ; lên đến OP hướng cụ thể để sử dụng.
RDFozz
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.