8 Stimmen

Sql gruppiert Zeilen mit gleichem Wert und setzt diesen Wert in die Kopfzeile?

Ich möchte Zeilen mit SQL gruppieren, meine Ergebnismenge ist folgende

Name Größe Datum
data1 123 12/03/2009
data1 124 15/09/2009
data2 333 02/09/2010
data2 323 02/11/2010
data2 673 02/09/2014
data2 444 05/01/2010

Ich möchte eine Ergebnismenge wie diese gruppieren:

Daten1
  123 12/03/2009
  124 15/09/2009
Daten2
  333 02/09/2010
  323 02/11/2010
  673 02/09/2014
  444 05/01/2010

Ist es möglich, dies mit reinem SQL zu tun?

Zum Wohl.

5 Stimmen

Was Sie vorhaben, sieht nach Formatierung aus, und die wird normalerweise am besten auf der Client-Seite vorgenommen.

0 Stimmen

Ja, das stimmt, aber ich spiele mit SQL und habe mich auch gefragt, ob es mit reinem SQL möglich ist :)

9voto

Cade Roux Punkte 85601

GROUP BY WITH ROLLUP (Sie sind nicht wirklich gruppiert - Sie würden also in Wirklichkeit GROUP BY jede Spalte)

http://dev.mysql.com/doc/refman/5.0/en/group-by-modifiers.html

http://chiragrdarji.wordpress.com/2008/09/09/group-by-cube-rollup-and-sql-server-2005/

http://databases.about.com/od/sql/l/aacuberollup.htm

http://www.adp-gmbh.ch/ora/sql/group_by/group_by_rollup.html

http://msdn.microsoft.com/en-us/library/bb522495.aspx

Basierend auf dem Code von Lieven:

DECLARE @Table TABLE (
     name varchar(32)
    ,Size integer
    ,Date datetime
    )

INSERT  INTO @Table
VALUES  ('data1', 123, GETDATE())
INSERT  INTO @Table
VALUES  ('data1', 124, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 333, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 323, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 673, GETDATE())
INSERT  INTO @Table
VALUES  ('data2', 444, GETDATE())

SELECT  *
FROM    (
         SELECT *
         FROM   @Table
         GROUP BY NAME
               ,size
               ,date
                WITH ROLLUP
        ) AS X
WHERE   NAME IS NOT NULL
        AND (
             (
              Size IS NOT NULL
              AND Date IS NOT NULL
             )
             OR (
                 Size IS NULL
                 AND date IS NULL
                )
            )
ORDER BY NAME
       ,size
       ,date

1 Stimmen

+1 für einen tapferen Einsatz. Bei der Verwendung dieser Abfrage, ich denke immer noch, dass der OP würde wichtige Lesbarkeit / Wartbarkeit alle im Namen der Formatierung zu opfern.

3voto

Lieven Keersmaekers Punkte 55277

Michael Todd hat definitiv Recht, wenn er sagt, dass dies auf der Client-Seite geschehen sollte, aber zum Spaß ist dies eine Möglichkeit

DECLARE @Table TABLE (name VARCHAR(32), Size INTEGER, Date DATETIME)

INSERT INTO @Table VALUES ('data1', 123, getdate())
INSERT INTO @Table VALUES ('data1', 124, getdate())
INSERT INTO @Table VALUES ('data2', 333, getdate())
INSERT INTO @Table VALUES ('data2', 323, getdate())
INSERT INTO @Table VALUES ('data2', 673, getdate())
INSERT INTO @Table VALUES ('data2', 444, getdate())

INSERT INTO @Table 
SELECT DISTINCT name, NULL, NULL
FROM @Table

SELECT 
  CASE WHEN Size IS NULL THEN Name ELSE NULL END
  , Size
  , Date
FROM @Table
ORDER BY Name, Size

3voto

Jules Bartow Punkte 71

Die Gestaltung der Daten im Voraus vereinfacht die Arbeit des Anwendungsentwicklers, vor allem, wenn er nur einen statischen Bericht ohne interaktives Bearbeiten, Sortieren oder Blättern anzeigen will - was häufig genug vorkommt.

Lievens Lösung (getrennte Auswahl der Spalten bei gleichzeitigem Einfügen von Nullen für andere Spalten, dann Prüfung auf Nullen der anderen Spalten) ist die einzige Lösung, die tatsächlich funktioniert. Irgendwie.

data1   NULL    NULL
NULL    123 2011-05-24 19:42:29.577
NULL    124 2011-05-24 19:42:29.577
data2   NULL    NULL
NULL    323 2011-05-24 19:42:29.577
NULL    333 2011-05-24 19:42:29.577
NULL    444 2011-05-24 19:42:29.577
NULL    673 2011-05-24 19:42:29.577

--es sei denn, die Spalte, die Sie nullen, hat bereits Nullen, in diesem Fall sind wir wieder bei Platz 0. Fügen Sie eine weitere Zeile hinzu.

INSERT INTO @Table VALUES ('data2', NULL, getdate())

Führen Sie nun die Abfrage erneut aus. Schade, Alter.

data1   NULL    NULL
NULL    123 2011-05-24 19:53:36.437
NULL    124 2011-05-24 19:53:36.437
data2   NULL    NULL
data2   NULL    2011-05-24 19:53:36.440
NULL    323 2011-05-24 19:53:36.440
NULL    333 2011-05-24 19:53:36.440
NULL    444 2011-05-24 19:53:36.440

Die von Roux vorgeschlagene ROLLUP-Lösung funktioniert überhaupt nicht, zumindest nicht in SQL Server. Sie macht die Dinge sogar noch schlimmer.

data1   NULL    NULL
data1   NULL    NULL
data1   NULL    NULL
data1   123 2011-05-24 20:16:26.693
data1   124 2011-05-24 20:16:26.693
data2   NULL    NULL
data2   NULL    NULL
data2   NULL    NULL
data2   323 2011-05-24 20:16:26.693
data2   333 2011-05-24 20:16:26.693
data2   444 2011-05-24 20:16:26.693
data2   673 2011-05-24 20:16:26.693

Pitis' ROWNUM-Lösung mag in Oracle funktionieren (ich habe es nicht ausprobiert, und es scheint, dass die Klammern am Anfang fehlen), aber der entsprechende SQL-Server-Code mit ROW_NUMBER() OVER funktioniert definitiv auch nicht gut - ungefähr so gut wie meine Grammatik und Rechtschreibung.

SELECT 
    ROW_NUMBER() OVER(ORDER BY [name]) AS [rown]
    , name
    , ''
    , ''
FROM @Table
GROUP BY name

UNION ALL

SELECT ROW_NUMBER() OVER(ORDER BY [name]) + 1 AS [rown] , name, size, date 
FROM @Table 

produziert

data1   NULL    NULL
data1   NULL    NULL
data1   NULL    NULL
data1   123 2011-05-24 20:16:26.693
data1   124 2011-05-24 20:16:26.693
data2   NULL    NULL
data2   NULL    NULL
data2   NULL    NULL
data2   323 2011-05-24 20:16:26.693
data2   333 2011-05-24 20:16:26.693
data2   444 2011-05-24 20:16:26.693
data2   673 2011-05-24 20:16:26.693

Als Softwareexperte ist es Ihre Aufgabe, dafür zu sorgen, dass Milliarden von 1en und 0en an der richtigen Stelle, in der richtigen Reihenfolge und zur richtigen Zeit aufgereiht werden. Sie wissen, dass die Details, oft bis auf ein einzelnes Bit, wichtig sind.

Eine halbherzige Antwort ist schlimmer als gar keine Antwort, denn sie verschwendet die Zeit aller Beteiligten. Also... nichts für ungut, denn die Absichten sind gut, aber bitte testen Sie zumindest Ihre "Lösung", bevor Sie sie als "Lösung" veröffentlichen.

Ich wäre perfekt, wenn ich nicht so verflixt bescheiden wäre. Und selbst ich teste.

2voto

Umair Anwar Punkte 367

Sie können zwei Abfragen verwenden und dann im Anwendungscode gruppieren/formatieren.

Erste Anfrage

SELECT DISTINCT(name) AS group_name FROM TABLE ORDER BY name LIMIT 5;

Zweite Anfrage

SELECT size, date FROM TABLE WHERE name IN ('comma separated group_name values from firstQueryResult');

Anwendungscode

for every row in firstQueryResult{
    group_array[group_name] = secondQueryResult;
}

Das resultierende group_array wird wie folgt aussehen;

data1
  123  12/03/2009
  124  15/09/2009
data2
  333  02/09/2010
  323  02/11/2010
  673  02/09/2014
  444  05/01/2010

1voto

Cătălin Pitiș Punkte 13785

Es könnte etwas sein wie:

select name, size, date from
(
-- select only distinct rows, and empty values for size and date (header rows)
select ROWNUM rown, name, '', ''
from T
group by name
order by name

union all

-- select all data (non-header records)
select ROWNUM+1 rown, name, size, date 
from T 
order by name
)
order by name, rown

Erläuterung: First select from the union wählt die Datensätze für die Gruppenüberschrift aus. Es sortiert die Ergebnisse nach Namen. Die Zeilennummer gibt die Reihenfolge an. Zweites select from the union wählt alle Datensätze für den Gruppenkopf aus. Die Ergebnisse werden nach dem Namen sortiert, und die Zeilennummer gibt die Reihenfolge an. Die Vereinigung fasst alle Informationen zusammen. ROWNUM+1 für den zweiten Select stellt sicher, dass die Datensätze für den Kopf (aus dem ersten Select) vor den detaillierten Datensätzen geordnet werden.

Nun... was Sie tun müssen, und ich nicht wiederherstellen, so viel SQL zu wissen, wie es zu tun... ist '' für den Namen zu setzen, wenn Größe oder Datum '', in der Hauptauswahl (mit einem Fall/swich Betrieb). Einige Hilfe wird hier benötigt :).

ROWNUM ist eine spezielle Spalte, die die Zeilennummer für einen Select angibt (siehe z. B. Oracle).

Die Abfrage wird grundsätzlich angezeigt, ich bin mir aber nicht 100%ig sicher, dass sie funktioniert.

Aktualisierung: ... das ist eine Lösungsskizze. Ich glaube aber immer noch, dass es sich um ein Formatierungsproblem und nicht um ein SQL-Problem handelt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X