2010-12-29 7 views
1

Ich weiß nicht, wie ich meine Frage klar stellen soll, damit ich Ihnen das Geld zeigen kann.Wie füge ich eine Spalte hinzu, die die Anzahl der verschiedenen Zeilen dieser Abfrage anzeigt?

mit zu starten, ist hier eine Beispieltabelle:

CREATE TABLE sandbox (
    id integer NOT NULL, 
    callsign text NOT NULL, 
    this text NOT NULL, 
    that text NOT NULL, 
    "timestamp" timestamp with time zone DEFAULT now() NOT NULL 
); 

CREATE SEQUENCE sandbox_id_seq 
    START WITH 1 
    INCREMENT BY 1 
    NO MINVALUE 
    NO MAXVALUE 
    CACHE 1; 

ALTER SEQUENCE sandbox_id_seq OWNED BY sandbox.id; 

SELECT pg_catalog.setval('sandbox_id_seq', 14, true); 

ALTER TABLE sandbox ALTER COLUMN id SET DEFAULT nextval('sandbox_id_seq'::regclass); 

INSERT INTO sandbox VALUES (1, 'alpha', 'foo', 'qux', '2010-12-29 16:51:09.897579+00'); 
INSERT INTO sandbox VALUES (2, 'alpha', 'foo', 'qux', '2010-12-29 16:51:36.108867+00'); 
INSERT INTO sandbox VALUES (3, 'bravo', 'bar', 'quxx', '2010-12-29 16:52:36.370507+00'); 
INSERT INTO sandbox VALUES (4, 'bravo', 'foo', 'quxx', '2010-12-29 16:52:47.584663+00'); 
INSERT INTO sandbox VALUES (5, 'charlie', 'foo', 'corge', '2010-12-29 16:53:00.742356+00'); 
INSERT INTO sandbox VALUES (6, 'delta', 'foo', 'qux', '2010-12-29 16:53:10.884721+00'); 
INSERT INTO sandbox VALUES (7, 'alpha', 'foo', 'corge', '2010-12-29 16:53:21.242904+00'); 
INSERT INTO sandbox VALUES (8, 'alpha', 'bar', 'corge', '2010-12-29 16:54:33.318907+00'); 
INSERT INTO sandbox VALUES (9, 'alpha', 'baz', 'quxx', '2010-12-29 16:54:38.727095+00'); 
INSERT INTO sandbox VALUES (10, 'alpha', 'bar', 'qux', '2010-12-29 16:54:46.237294+00'); 
INSERT INTO sandbox VALUES (11, 'alpha', 'baz', 'qux', '2010-12-29 16:54:53.891606+00'); 
INSERT INTO sandbox VALUES (12, 'alpha', 'baz', 'corge', '2010-12-29 16:55:39.596076+00'); 
INSERT INTO sandbox VALUES (13, 'alpha', 'baz', 'corge', '2010-12-29 16:55:44.834019+00'); 
INSERT INTO sandbox VALUES (14, 'alpha', 'foo', 'qux', '2010-12-29 16:55:52.848792+00'); 

ALTER TABLE ONLY sandbox 
    ADD CONSTRAINT sandbox_pkey PRIMARY KEY (id); 

Hier ist die aktuelle SQL-Abfrage Ich habe:

SELECT 
    * 
FROM 
(
    SELECT 
     DISTINCT ON (this, that) 

     id, this, that, timestamp 
    FROM 
     sandbox 
    WHERE 
     callsign = 'alpha' 
      AND 
     CAST(timestamp AS date) = '2010-12-29' 
) 
    playground 
ORDER BY 
    timestamp 
DESC 

Dies ist das Ergebnis es gibt mir:

id  this that timestamp 
----------------------------------------------------- 
14  foo  qux  2010-12-29 16:55:52.848792+00 
13  baz  corge 2010-12-29 16:55:44.834019+00 
11  baz  qux  2010-12-29 16:54:53.891606+00 
10  bar  qux  2010-12-29 16:54:46.237294+00 
9  baz  quxx 2010-12-29 16:54:38.727095+00 
8  bar  corge 2010-12-29 16:54:33.318907+00 
7  foo  corge 2010-12-29 16:53:21.242904+00 

Das möchte ich sehen:

id  this that timestamp      count 
------------------------------------------------------------- 
14  foo  qux  2010-12-29 16:55:52.848792+00 3 
13  baz  corge 2010-12-29 16:55:44.834019+00 2 
11  baz  qux  2010-12-29 16:54:53.891606+00 1 
10  bar  qux  2010-12-29 16:54:46.237294+00 1 
9  baz  quxx 2010-12-29 16:54:38.727095+00 1 
8  bar  corge 2010-12-29 16:54:33.318907+00 1 
7  foo  corge 2010-12-29 16:53:21.242904+00 1 

EDIT:

Ich bin mit PostgreSQL 9.0 * (wenn das hilft vorhanden)..

Antwort

4

Ich habe postgre nicht installiert, aber ich habe diese auf SQL Server, ich glaube, Sie auf die Idee verwenden können:

CREATE TABLE sandbox (
    id integer NOT NULL, 
    callsign varchar(1000) NOT NULL, 
    this varchar(1000) NOT NULL, 
    that varchar(1000) NOT NULL, 
    tm datetime NOT NULL 
); 


INSERT INTO sandbox VALUES (1, 'alpha', 'foo', 'qux', '2010-12-29 16:51:09'); 
INSERT INTO sandbox VALUES (2, 'alpha', 'foo', 'qux', '2010-12-29 16:51:36'); 
INSERT INTO sandbox VALUES (3, 'bravo', 'bar', 'quxx', '2010-12-29 16:52:36'); 
INSERT INTO sandbox VALUES (4, 'bravo', 'foo', 'quxx', '2010-12-29 16:52:47'); 
INSERT INTO sandbox VALUES (5, 'charlie', 'foo', 'corge', '2010-12-29 16:53:00'); 
INSERT INTO sandbox VALUES (6, 'delta', 'foo', 'qux', '2010-12-29 16:53:10'); 
INSERT INTO sandbox VALUES (7, 'alpha', 'foo', 'corge', '2010-12-29 16:53:21'); 
INSERT INTO sandbox VALUES (8, 'alpha', 'bar', 'corge', '2010-12-29 16:54:33'); 
INSERT INTO sandbox VALUES (9, 'alpha', 'baz', 'quxx', '2010-12-29 16:54:38'); 
INSERT INTO sandbox VALUES (10, 'alpha', 'bar', 'qux', '2010-12-29 16:54:46'); 
INSERT INTO sandbox VALUES (11, 'alpha', 'baz', 'qux', '2010-12-29 16:54:53'); 
INSERT INTO sandbox VALUES (12, 'alpha', 'baz', 'corge', '2010-12-29 16:55:39'); 
INSERT INTO sandbox VALUES (13, 'alpha', 'baz', 'corge', '2010-12-29 16:55:44'); 
INSERT INTO sandbox VALUES (14, 'alpha', 'foo', 'qux', '2010-12-29 16:55:52'); 

    SELECT max(id), this, that, min(tm), COUNT(*) 
    FROM sandbox 
    WHERE 
     callsign = 'alpha' 
     AND 
     CAST(tm AS date) = '2010-12-29' 
    GROUP BY this, that 
    ORDER BY MAX(id) DESC 

Ausgang:

14 foo qux 2010-12-29 16:51:09.000 3 
13 baz corge 2010-12-29 16:55:39.000 2 
11 baz qux 2010-12-29 16:54:53.000 1 
10 bar qux 2010-12-29 16:54:46.000 1 
9 baz quxx 2010-12-29 16:54:38.000 1 
8 bar corge 2010-12-29 16:54:33.000 1 
7 foo corge 2010-12-29 16:53:21.000 1 
+0

Das funktioniert sicherlich. Ich kann sehen, dass Sie Aggregatfunktionen für 'id' und' tm' verwendet haben, um die Verwendung von 'GROUP BY' zu ermöglichen. In Situationen wie diesen, wann benutzt du eine über der anderen? Warum haben Sie zum Beispiel "max" auf "id" gesetzt oder macht das keinen Unterschied? –

+0

Ich bevorzuge die Gruppe generell, weil sie deterministischer ist. Mit distinct auf Sie können zufällige Antworten für die nicht-distinct auf Elemente in der Auswahlliste. Auch in PostgreSQL ist group by vom Abfrageplaner stärker zu optimieren als eindeutig auf. Bei größeren Sets kann der Leistungsunterschied ziemlich groß sein. –

+0

@Scott Marlowe: Ich stimme zu, es ist eher deterministisch. Was mich daran hinderte, es zu benutzen, war nicht zu wissen, wie ich den Aggregatfunktionsfehler umgehen konnte, besonders wenn ich nicht wollte, dass die Werte, auf die er Fehler warf, gruppiert wurden. Die Verwendung von "min" und "max" scheint das zu umgehen, aber ich bin mir nicht sicher, wie es genau funktioniert. –

0

dcp Lösung funktioniert. Getestet auf Postgres.

BTW, sollten Sie Zeitstempel als Spaltenname vermeiden, da es ein reserviertes Wort ist und in Anführungszeichen gesetzt werden muss.

+0

eine 'Spalte Dies werfen * muss in der GROUP BY-Klausel vorkommen oder in einem Aggregatfunktionsfehler für "id" und "timestamp" verwendet werden. Die Lösung wird dann die Ergebnisse vollständig aufspießen. –

+0

Können Sie das '*' nicht mit 'that' ersetzen, indem Sie die Anzahl der gruppierten' thats' zählen? – Jaymz

Verwandte Themen