tsql group durch alphanumerischen Spaltenwert mit maximaler Länge

Ich habe eine Sql-view, nennen wir es SampleView , dessen Ergebnisse das folgende Format haben.

 Id (INT), NameA (VARVHAR(50)), NameB (VARCHAR(50)), ValueA (INT), ValueB (INT) 

Der Ergebnissatz der view enthält Zeilen, die dieselbe Id oder nicht haben können. Wenn es zwei oder mehr Zeilen mit der gleichen Id gibt, würde ich gerne etwas wie das folgende bekommen

 SELECT Id, MAX(NameA), MAX(NameB), MAX(ValueA), MAX(ValueB) FROM SampleView GROUP BY Id ORDER BY Id 

In Bezug auf die Spalten Id , ValueA und ValueB gibt es kein Problem. Auf der anderen Seite mit MAX für NameA und NameB Dinge sind nicht wie erwartet. Nach einigen googeln und suchen habe ich erkannt, dass MAX nicht das "erwartete" Verhalten für alphanumerische Spalten hat. Wenn ich das erwartete, ich meine mit MAX in meinem Fall, wäre es, den Wert von NameA mit der maximalen Anzahl von character, MAX(LEN(NameA)) . Ich muss hier erwähnen, dass es keine Möglichkeit für NameA gibt, zwei Werte für die gleiche Id mit der gleichen Länge zu haben. Dies macht das Problem einfacher zu lösen.

Ich verwende SQL server 2012 und TSQL .

Haben Sie irgendeinen Vorschlag, wie ich mit diesem Problem umgehen könnte?

Vielen Dank im Voraus für jede Hilfe.

Sie können windowsfunktionen verwenden:

 SELECT DISTINCT id, FIRST_VALUE(NameA) OVER (PARTITION BY id ORDER BY len(NameA) DESC) AS MaxNameA, MAX(ValueA) OVER (PARTITION BY id) AS MaxValueA, FIRST_VALUE(NameB) OVER (PARTITION BY id ORDER BY len(NameB) DESC) AS MaxNameB, MAX(ValueB) OVER (PARTITION BY id) AS MaxValueB FROM SampleView 

Demo hier

Sie können korrelierte Abfragen wie folgt verwenden:

 SELECT t.Id, (SELECT TOP 1 s.NameA FROM SampleView s WHERE s.id = t.id ORDER BY length(s.NameA) DESC) as NameA, (SELECT TOP 1 s.NameB FROM SampleView s WHERE s.id = t.id ORDER BY length(s.NameB) DESC) as NameB, MAX(t.ValueA), MAX(t.ValueB) FROM SampleView t GROUP BY t.Id ORDER BY t.Id 

Eine mögliche Variante ist es, ROW_NUMBER zweimal zu verwenden:

 WITH CTE_NameA AS ( SELECT Id, NameA, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY LEN(NameA) DESC) AS rnA FROM SampleView ) ,CTE_NameB AS ( SELECT Id, NameB, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY LEN(NameB) DESC) AS rnB FROM SampleView ) SELECT Id, CTE_NameA.NameA, CTE_NameB.NameB, MAX(ValueA), MAX(ValueB) FROM SampleView INNER JOIN CTE_NameA ON CTE_NameA.Id = SampleView.Id AND CTE_NameA.rnA = 1 INNER JOIN CTE_NameB ON CTE_NameB.Id = SampleView.Id AND CTE_NameB.rnB = 1 GROUP BY Id ORDER BY Id;