2009-09-01 18 views
5

Ich brauche eine Abfrage, die eine Tabelle zurückgibt, wobei jede Spalte die Anzahl der verschiedenen Werte in den Spalten einer anderen Tabelle ist.SQL: Anzahl der verschiedenen Werte in jeder Spalte

Ich weiß, wie die unterschiedlichen Werte in einer Spalte zählen:

select count(distinct columnA) from table1; 

Ich nehme an, dass ich nur diese eine wirklich lange select-Klausel machen könnte:

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

aber das ist nicht sehr elegant und es ist hart codiert. Ich würde etwas flexibleres bevorzugen.

+1

Dies ist die elegante und einfachste Lösung ... meinst du "gegeben einen Tabellennamen, geben Sie mir verschiedene Zählungen für jede Spalte in dieser Tabelle"? – gbn

+1

Welche Datenbank benutzen Sie? –

+0

Mögliches Duplikat: http://StackOverflow.com/Questions/1330692/Distinct-Pair-of-Values-SQL –

Antwort

0

ich alle Antworten zu schätzen wissen. Ich denke, die Lösung, die für mich in dieser Situation am besten funktioniert (Zählen der Anzahl der verschiedenen Werte in jeder Spalte einer Tabelle von einem externen Programm, das die Tabelle außer seinem Namen nicht kennt) ist:

Run "Beschreibe table1" und ziehe die Spaltennamen aus dem Ergebnis heraus.

Durchlaufen Sie die Spaltennamen und erstellen Sie die Abfrage, um die unterschiedlichen Werte in jeder Spalte zu zählen. Die Abfrage wird etwa so aussehen: "Anzahl auswählen (unterschiedliche SpalteA), Anzahl (eindeutige SpalteB), ... aus Tabelle1".

1

Dieser Code sollte Ihnen alle Spalten in 'table1' mit den jeweils unterschiedlichen Wert für jede als Daten geben.

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

und es ist hartcodiert.

Es ist nicht hardcoding, eine Feldliste für eine SQL-Anweisung bereitzustellen. Es ist üblich und akzeptabel.

+0

... Wie programmatisch das SQL erstellt wird, so weit wie es geht (vorausgesetzt, Ihre Benutzer liefern nie die Werte, die Sie eingeben - gut in dieser Frage, Sie haben die Spaltenliste irgendwo). – ijw

+0

Wenn ich Code-gen SQL, und wenn ich auf MSSqlServer war, würde ich sysObjects und syscolumns auschecken. –

+0

Wenn Sie den Code portabler schreiben möchten, sollten Sie aus Information_Schema.Tables und Information_Schema auswählen.Spalten, anstatt aus sysobjects und syscolumns auszuwählen – Kibbee

-3

DISTINCT ist böse. ZÄHLEN/GRUPPE BY

+0

Bitte qualifizieren Sie dies mit weiteren Informationen. Wie benutzt man distinct bösen, wenn man COUNT/GROUP BY ausführt? – Kibbee

+0

DISTINCT verhält sich bei größeren Datensätzen und von Plattform zu Plattform unregelmäßig. Zumindest in meiner Erfahrung. Ich finde Gruppierungsergebnisse berechenbarer, vor allem, wenn Sie mit anders codierten Daten, UTF, etc. umgehen. –

+0

Ich werde in der Verwendung der Gruppe nach suchen müssen. – Ryan

0

Dies ist nicht unbedingt für jedes Feld in einer Tabelle möglich. Beispielsweise können Sie eine DISTINCT für ein SQL Server-ntext- oder -Bildfeld nicht ausführen, wenn Sie sie nicht in andere Datentypen umwandeln und dadurch die Genauigkeit verlieren.

+0

Guter Punkt. Ich sollte mir deswegen keine Sorgen machen müssen. Die Felder sind nur Text oder Zahlen. – Ryan

3

versuchen, diese (SQL Server 2005-Syntax):

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: Prägnant, elegant, frech ... – gbn

Verwandte Themen