2009-09-01 70 views
5

Tôi cần truy vấn trả về bảng trong đó mỗi cột là số giá trị riêng biệt trong các cột của bảng khác.SQL: đếm số giá trị riêng biệt trong mỗi cột

tôi biết làm thế nào để đếm số giá trị khác biệt trong một cột:

select count(distinct columnA) from table1; 

Tôi cho rằng tôi chỉ có thể thực hiện điều này thực sự dài chọn khoản:

select count(distinct columnA), count(distinct columnB), ... from table1; 

nhưng đó không phải là rất thanh lịch và nó cứng. Tôi muốn một cái gì đó linh hoạt hơn.

+1

Đây là giải pháp thanh lịch và đơn giản nhất ... ý bạn là "đặt tên bảng, cho tôi số lượng riêng biệt cho mỗi cột trong bảng đó"? – gbn

+1

Bạn đang sử dụng cơ sở dữ liệu nào? –

+0

Có thể trùng lặp: http://stackoverflow.com/questions/1330692/distinct-pair-of-values-sql –

Trả lời

0

Tôi đánh giá cao tất cả các câu trả lời. Tôi nghĩ rằng giải pháp sẽ làm việc tốt nhất cho tôi trong tình huống này (đếm số giá trị riêng biệt trong mỗi cột của bảng từ một chương trình bên ngoài không có kiến ​​thức về bảng ngoại trừ tên của nó) như sau:

Chạy "mô tả table1" và kéo ra khỏi các tên cột từ kết quả.

Lặp qua các tên cột và tạo truy vấn để tính các giá trị khác biệt trong mỗi cột. Truy vấn sẽ trông giống như "số đếm (cột riêng biệt A), số đếm (cột riêng biệt B), ... từ bảng 1".

1

Mã này sẽ cung cấp cho bạn tất cả các cột trong 'table1' với số giá trị riêng biệt tương ứng cho từng cột dưới dạng dữ liệu.

DECLARE @TableName VarChar (Max) = 'table1' 
DECLARE @SqlString VarChar (Max) 

set @SqlString = (
    SELECT DISTINCT 
    'SELECT ' + 
     RIGHT (ColumnList, LEN (ColumnList)-1) + 
     ' FROM ' + Table_Name 
    FROM INFORMATION_SCHEMA.COLUMNS COL1 
     CROSS AppLy (
     SELECT ', COUNT (DISTINCT [' + COLUMN_NAME + ']) AS ' + '''' + COLUMN_NAME + '''' 
      FROM INFORMATION_SCHEMA.COLUMNS COL2 
      WHERE COL1.TABLE_NAME = COL2.TABLE_NAME 
      FOR XML PATH ('') 
    ) TableColumns (ColumnList) 
    WHERE 
     1=1 AND 
     COL1.TABLE_NAME = @TableName 
) 

EXECUTE (@SqlString) 
1

và mã được mã hoá cứng.

Nó không phải là mã hóa cứng để cung cấp danh sách trường cho câu lệnh sql. Đó là thực hành phổ biến và chấp nhận được.

+0

... Như đã tạo lập trình SQL, theo cách lập trình (cung cấp cho người dùng của bạn không bao giờ cung cấp các giá trị bạn đưa vào nó - tốt trong câu hỏi này, bạn có danh sách cột ở đâu đó). – ijw

+0

nếu tôi định sử dụng mã SQL, và nếu tôi đang sử dụng MSSqlServer, tôi sẽ kiểm tra sysobjects và syscolumns. –

+0

Nếu bạn muốn viết mã theo cách di động hơn, bạn nên chọn từ Information_Schema.Tables và Information_Schema.Cột, thay vì chọn từ sysobjects và syscolumns – Kibbee

-3

DISTINCT là điều xấu. Do COUNT/GROUP BY

+0

Vui lòng hội đủ điều kiện này với nhiều thông tin hơn. Làm thế nào là sử dụng ác độc hại khi compred để làm COUNT/GROUP BY? – Kibbee

+0

DISTINCT hoạt động không đúng với các tập dữ liệu lớn hơn và từ nền tảng đến nền tảng. Ít nhất là trong kinh nghiệm của tôi. Tôi thấy kết quả nhóm có thể dự đoán được nhiều hơn, đặc biệt nếu bạn xử lý dữ liệu được mã hóa khác, UTF, v.v. –

+0

Tôi sẽ phải xem xét sử dụng nhóm theo. – Ryan

0

Điều này không nhất thiết phải có thể cho mọi trường trong bảng. Ví dụ, bạn không thể làm DISTINCT đối với trường ntext hoặc hình ảnh của Máy chủ SQL trừ khi bạn truyền chúng sang các loại dữ liệu khác và mất một số độ chính xác.

+0

Điểm tốt. Tôi không cần phải lo lắng về điều này. Các trường sẽ chỉ là văn bản hoặc số. – Ryan

3

thử (sql cú pháp server 2005) này:

DECLARE @YourTable table (col1 varchar(5) 
         ,col2 int 
         ,col3 datetime 
         ,col4 char(3) 
         ) 

insert into @YourTable values ('abcdf',123,'1/1/2009','aaa') 
insert into @YourTable values ('aaaaa',456,'1/2/2009','bbb') 
insert into @YourTable values ('bbbbb',789,'1/3/2009','aaa') 
insert into @YourTable values ('ccccc',789,'1/4/2009','bbb') 
insert into @YourTable values ('aaaaa',789,'1/5/2009','aaa') 
insert into @YourTable values ('abcdf',789,'1/6/2009','aaa') 


;with RankedYourTable AS 
(
SELECT 
    ROW_NUMBER() OVER(PARTITION by col1 order by col1) AS col1Rank 
     ,ROW_NUMBER() OVER(PARTITION by col2 order by col2) AS col2Rank 
     ,ROW_NUMBER() OVER(PARTITION by col3 order by col3) AS col3Rank 
     ,ROW_NUMBER() OVER(PARTITION by col4 order by col4) AS col4Rank 
    FROM @YourTable 
) 
SELECT 
    SUM(CASE WHEN  col1Rank=1 THEN 1 ELSE 0 END) AS col1DistinctCount 
     ,SUM(CASE WHEN col2Rank=1 THEN 1 ELSE 0 END) AS col2DistinctCount 
     ,SUM(CASE WHEN col3Rank=1 THEN 1 ELSE 0 END) AS col3DistinctCount 
     ,SUM(CASE WHEN col4Rank=1 THEN 1 ELSE 0 END) AS col4DistinctCount 
    FROM RankedYourTable 

OUTPUT:

col1DistinctCount col2DistinctCount col3DistinctCount col4DistinctCount 
----------------- ----------------- ----------------- ----------------- 
4     3     6     2 

(1 row(s) affected) 
+0

+1: Ngắn gọn, thanh lịch, táo bạo ... – gbn

Các vấn đề liên quan