2017-12-19 6 views
1

Es ist alles im Titel. Dokumentation hat etwas Ähnliches:Können die Kategorien in der postgres tablefunc-Funktion crossstab() ganze Zahlen sein?

SELECT * 
FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text); 

Ich habe zwei Tabellen, lab_tests und lab_tests_results. Alle lab_tests_results Zeilen sind an die Primärschlüssel-ID-Ganzzahl in der lab_tests Tabelle gebunden. Ich versuche, eine Pivot-Tabelle zu machen, wo die Labortests (identifiziert durch eine Ganzzahl) Zeilenköpfe sind und die entsprechenden Ergebnisse in der Tabelle sind. Ich kann einen Syntaxfehler um oder um die ganze Zahl nicht umgehen.

Ist dies mit der aktuellen Einrichtung möglich? Fehle ich etwas in der Dokumentation? Oder muss ich einen inneren Join der Art durchführen, um die Kategorien Strings zu machen? Oder ändern Sie die lab_tests_results Tabelle, um eine Textkennung für die Labortests zu verwenden?

Danke für die Hilfe, alle. Sehr geschätzt.

Bearbeiten: Habe es mit Hilfe von Dmitry herausgefunden. Er hatte das Datenlayout herausgefunden, aber ich wusste nicht, welche Art von Ausgabe ich brauchte. Ich habe versucht, die Pivot-Tabelle auf Batch_ID-Nummern in der Tabelle lab_tests_results basieren zu lassen. Musste die Base-Abfrage und Casting-Datentypen hämmern.

SELECT * 
FROM crosstab('SELECT lab_tests_results.batch_id, lab_tests.test_name, lab_tests_results.test_result::FLOAT 
       FROM lab_tests_results, lab_tests 
       WHERE lab_tests.id=lab_tests_results.lab_test AND (lab_tests.test_name LIKE ''Test Name 1'' OR lab_tests.test_name LIKE ''Test Name 2'') 
       ORDER BY 1,2' 
      ) AS final_result(batch_id VARCHAR, test_name_1 FLOAT, test_name_2 FLOAT); 

Diese eine Pivot-Tabelle wie unten aus der lab_tests_results Tabelle:

batch_id |test_name_1 |test_name_2 
--------------------------------------- 
batch1  | result1 | <null> 
batch2  | result2 | result3 

Antwort

1

Wenn ich in etwa so aussehen richtig Ihre Tabellen verstehen:

CREATE TABLE lab_tests (
    id INTEGER PRIMARY KEY, 
    name VARCHAR(500) 
); 

CREATE TABLE lab_tests_results (
    id INTEGER PRIMARY KEY, 
    lab_tests_id INTEGER REFERENCES lab_tests (id), 
    result TEXT 
); 

Und Ihre Daten sieht etwa so aus dies:

INSERT INTO lab_tests (id, name) 
VALUES (1, 'test1'), 
     (2, 'test2'); 

INSERT INTO lab_tests_results (id, lab_tests_id, result) 
VALUES (1,1,'result1'), 
     (2,1,'result2'), 
     (3,2,'result3'), 
     (4,2,'result4'), 
     (5,2,'result5'); 

Vor allem crosstab Teil tablefunc ist, müssen Sie es aktivieren:

CREATE EXTENSION tablefunc; 

Sie benötigen es, eine pro Datenbank als pro this Antwort laufen.

Die letzte Abfrage wird wie folgt aussehen:

SELECT * 
FROM crosstab(
    'SELECT lt.name::TEXT, lt.id, ltr.result 
    FROM lab_tests AS lt 
    JOIN lab_tests_results ltr ON ltr.lab_tests_id = lt.id' 
) AS ct(test_name text, result_1 text, result_2 text, result_3 text); 

Erläuterung:
Die crosstab() Funktion einen Text einer Abfrage dauert, die 3 Spalten zurückgeben sollte; (1) eine Spalte für den Namen einer Gruppe, (2) eine Spalte für die Gruppierung, (3) der Wert. Die Wrapping-Abfrage wählt nur alle Werte aus, die zurückgibt und definiert die Liste der Spalten nach (der Teil nach AS). Zuerst ist der Kategoriename (test_name) und dann die Werte (result_1, result_2). In meiner Abfrage bekomme ich bis zu 3 Ergebnisse. Wenn ich mehr als 3 Ergebnisse habe, werde ich sie nicht sehen. Wenn ich weniger als 3 Ergebnisse habe, bekomme ich Nullen.

Das Ergebnis dieser Abfrage ist:

test_name |result_1 |result_2 |result_3 
--------------------------------------- 
test1  |result1 |result2 |<null> 
test2  |result3 |result4 |result5 
+0

Dank Dmitry. Habe die Ausgabe, die ich herausfinden wollte, von dem, was du geliefert hast. Bearbeitete meinen ursprünglichen Beitrag, um das zu zeigen. – user1644030

Verwandte Themen