2012-04-04 5 views
0

können sagen, ich habe Tabelle mit ID int, VALUE string:effektivste Weg, Wert zu erhalten, wenn select count (*) = 1 mit Gruppierung

ID | VALUE 
1  abc 
2  abc 
3  def 
4  abc 
5  abc 
6  abc 

Wenn ich wählen Wert tun, count (*) Gruppe Wert soll ich

VALUE | COUNT 
abc  5 
def  1 

nun den schwierigen Teil erhalten, wenn es Zahl == 1 ich diese ID aus dem ersten Tabelle erhalten muß, ist. Soll ich CTE verwenden? Ergebnismenge erstellen, wo ich ID String == null hinzufügen und aktualisieren b.ID = a.ID wo count == 1?

Oder gibt es einen anderen einfacheren Weg?

EDIT:

Ich möchte wie diese Ergebnistabelle haben:

ID  VALUE count 
null abc 5 
3  def 1 

Antwort

3

Wenn Ihre ID-Werte eindeutig sind, können Sie einfach überprüfen um zu sehen, ob das Maximum (id) = min (id) ist. Wenn ja, dann verwenden Sie entweder eins, andernfalls können Sie null zurückgeben. Wie folgt aus:

Select Case When Min(id) = Max(id) Then Min(id) Else Null End As Id, 
     Value, Count(*) As [Count] 
From YourTable 
Group By Value 

Da Sie bereits ein Aggregat durchführen, einschließlich der Min- und Max-Funktion ist wahrscheinlich keine extra (spürbar) Zeit in Anspruch nehmen. Ich ermutige Sie, dies zu versuchen.

+0

Das ist viel besser als meine hässliche Union. Ich applaudiere Ihnen, mein Herr. Ist der Fall bei großen Abfragen ein potenzieller Leistungseinbruch? –

+0

@CrisCarew Ich habe die Leistung im Vergleich zu Ihrem Vorschlag überprüft, und dies ist besser. Sie sehen, ich treffe nur einmal den Tisch. SQL Server muss das Zählaggregat für jede Gruppe durchführen. Wenn Sie das Min- und Max-Aggregat entlang des Weges ausführen, wirkt sich dies nicht zu sehr auf die Leistung aus. Die case-Anweisung wird erst angewendet, wenn alle Aggregate einmal pro Gruppe ausgeführt wurden. –

+0

Ich dachte mir so viel. Kühle Bohnen. Ich habe etwas gelernt, indem ich heute etwas beantwortet habe. –

-1

vielleicht nicht die effizienteste, aber so etwas wie dies funktioniert:

SELECT MAX(Id) as ID,Value FROM Table WHERE COUNT(*) = 1 GROUP BY Value 
0

Wenn Gruppe mit durch, nachdem die Gruppe nach Anweisung können Sie eine Having-Klausel verwenden.

So

SELECT [ID] 
FROM table 
GROUP BY [VALUE] 
HAVING COUNT(*) = 1 

Edit: in Bezug auf Ihre editierten Frage: diese verwendet einiger Spaß und Gewerkschaften

CREATE TABLE #table 
(ID int IDENTITY, 
VALUE varchar(3)) 

INSERT INTO #table (VALUE) 
VALUES('abc'),('abc'),('def'),('abc'),('abc'),('abc') 

    SELECT * FROM (
    SELECT Null as ID,VALUE, COUNT(*) as [Count] 
    FROM #table 
    GROUP BY VALUE 
    HAVING COUNT(*) > 1 
UNION ALL 
    SELECT t.ID,t.VALUE,p.Count FROM 
    #table t 
    JOIN 
    (SELECT VALUE, COUNT(*) as [Count] 
    FROM #table 
    GROUP BY VALUE 
    HAVING COUNT(*) = 1) p 
    ON t.VALUE=p.VALUE 
) a 



DROP TABLE #table 
+0

Sorry, bearbeitete Seite, um zu sehen, wie Ergebnis aussehen sollte – feronovak

+0

Nein. Die ID-Spalte müsste gruppiert oder aggregiert sein, um in der Auswahlliste gültig zu sein. – KeithS

+0

@KeithS eine einfache Lösung mit einem Join. Bearbeitet, um eine korrekte Lösung hinzuzufügen. –

0

Die Art und Weise verbindet ich es in der Tat zu tun wäre ein CTE wäre:

using @group AS (SELECT value, Count(*) as count from MyTable GROUP BY value HAVING count = 1) 
SELECT MyTable.ID, @group.value, @group.count from MyTable 
    JOIN @group ON @group.value = MyTable.value 
+0

Sorry, bearbeitete Seite, um zu sehen, wie Ergebnis aussehen sollte – feronovak

+0

Bearbeitet, um die richtige Auswahlliste zu haben. – KeithS