Ich habe derzeit die folgende SQL-Abfrage:

SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2008_2009
    ,DPISTAFF2009_2010
    ,DPISTAFF2010_2011
    ,DPISTAFF2011_2012
    ,DPISTAFF2012_2013
    ,DPISTAFF2013_2014
    ,DPISTAFF2014_2015
    ,DPISTAFF2015_2016
WHERE DPISTAFF2015_2016.FirstName = 'George'

Es gibt mehrere Tabellen mit jeweils derselben Art von Informationen für jedes Jahr. Ich möchte alle Datensätze aus jeder Tabelle abrufen, die mit den WHERE-Informationen übereinstimmen. Angenommen, George ist einzigartig, wäre das 1 Eintrag aus jeder Tabelle, damit ich seine Informationen für jedes Jahr vergleichen kann.

Ich erhalte den "ambivalent_column_error", obwohl ich meiner WHERE-Anweisung eine Tabellen-ID hinzugefügt habe. Muss ich noch etwas hinzufügen, damit dies funktioniert?

AKTUALISIERTE ABFRAGE: Ich habe versucht, um zu sehen, ob es funktionieren würde. Hier habe ich nur 2 Tabellen anstelle aller 6, damit ich versuchen kann, es zum Laufen zu bringen, bevor ich all diese Arbeit erledige (und wahrscheinlich würde ich bei der Implementierung Variablen verwenden, damit ich den Namen leicht ändern kann). Es hat nicht. Ich bekomme near ";": syntax error

CREATE TEMP TABLE IF NOT EXISTS _Variables (Name TEXT PRIMARY KEY, Value TEXT);
INSERT OR REPLACE INTO _Variables VALUES ('VarFirstName', 'John');
INSERT OR REPLACE INTO _Variables VALUES ('VarLastName', 'Smith');

SELECT LastName,FirstName,BirthYear,(strftime('%Y', date('now')) - BirthYear) AS Age,LocalExp,TotalExp,TotSalary,TotFringe,WorkLocationName,SchoolName
FROM DPISTAFF2008_2009
WHERE DPISTAFF2008_2009.FirstName = (SELECT Value FROM _Variables WHERE Name = 'VarFirstName')
    AND DPISTAFF2008_2009.LastName = (SELECT Value FROM _Variables WHERE Name = 'VarLastName')
UNION ALL

SELECT LastName,FirstName,BirthYear,(strftime('%Y', date('now')) - BirthYear) AS Age,LocalExp,TotalExp,TotSalary,TotFringe,WorkLocationName,SchoolName
FROM DPISTAFF2009_2010
WHERE DPISTAFF2009_2010.FirstName = (SELECT Value FROM _Variables WHERE Name = 'VarFirstName')
    AND DPISTAFF2009_2010.LastName = (SELECT Value FROM _Variables WHERE Name = 'VarLastName')
UNION ALL

;DROP TABLE _Variables;

Wenn ich dies nur einmal aus einer Tabelle ohne UNION ALLs mache, gibt die Abfrage erfolgreich 1 Datensatz aus dieser Tabelle zurück.

0
InterLinked 19 Apr. 2018 im 19:53

3 Antworten

Beste Antwort

Da Ihr Tabellenschema nicht so gut ist (dies sollte alles eine Tabelle in Kombination mit einer 'Jahr'-Spalte sein), müssen Sie eine große Vereinigung durchführen:

SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2008   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2009   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2010   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2011   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2012   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2013   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2014   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2015   
WHERE FirstName = 'George'
UNION ALL
SELECT LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF2016   
WHERE FirstName = 'George'

Aktualisieren Sie, um mehr über das Schema zu erfahren.

Ein besseres Schema, das die Auswahl für diese Daten beschleunigt und die Komplexität dieser SQL und Daten drastisch reduziert, ist wie folgt:

CREATE TABLE DPISTAFF
(
    recordyear int,
    LastName varchar(100),
    FirstName varchar(100),
    BirthYear int,
    LocalExp varchar(20),
    TotalExp  varchar(20),
    TotSalary Decimal (18,2),
    TotFringe Decimal(18,2)
    WorkLocationName varchar(100)
    SchoolName varchar(100)
);

Sie können dann einen Index für firstname erstellen, um eine Auswahl für eine bestimmte Person SEHR schnell zu treffen.

CREATE INDEX dpistaff_firstname ON dpistaff (firstname);

Jetzt ist Ihre Anfrage nur noch:

SELECT  
    RecordYear
    ,LastName
    ,FirstName
    ,BirthYear
    ,LocalExp
    ,TotalExp
    ,TotSalary
    ,TotFringe
    ,WorkLocationName
    ,SchoolName
FROM DPISTAFF
WHERE Firstname = 'George';

Wenn Sie feststellen, dass Sie sehr oft ein Jahr auswählen, z. B. "Gib mir alle für 2008", können Sie auch einen Index für das Rekordjahr hinzufügen. Sie können auch (oder alternativ) einen Index für (recordYear, FirstName) wünschen, wenn Sie häufig für beide gleichzeitig auswählen, z. B. "Geben Sie mir Bills Daten für 2016".

Wenn Ihr RDBMS die Partitionierung unterstützt, können Sie anstelle des Index eine Partition für das Rekordjahr in Betracht ziehen. Ich vermute jedoch anhand Ihrer Syntax, dass Sie sich auf sqlLite befinden, sodass die Indizes hier ausreichen müssen. Außerdem sind Ihre Daten ziemlich klein, sodass ein Partitionierungsschema möglicherweise etwas übertrieben ist.

Der große Nachteil dabei ist, dass Ihr Schema wahrscheinlich nicht großartig ist, wenn Sie häufig eine neue Tabelle erstellen oder Spalten hinzufügen müssen, nur weil wir uns in einem neuen Monat / Quartal / Jahr befinden. Wir möchten das Schema einmal erstellen und dann jahrelang verwenden. Fügen Sie nur neue Objekte (Datenbanken, Tabellen, Spalten) hinzu, wenn Sie neue Objekte hinzufügen. In diesem Fall eine neue Tabelle zum Speichern von Attributen von "School" wie SchoolAddress, SchoolPhone. Und dann vielleicht später eine Tabelle hinzufügen, um ClassRooms und seine Attribute zu speichern.

3
JNevill 20 Apr. 2018 im 13:35

Alle DPISTAFF-Tabellen haben dieselben Spalten. Ich würde empfehlen, eine Prozedur zu erstellen, die einen Namen als Eingabe verwendet.

Verwenden Sie im Rahmen des Verfahrens Folgendes:

select LastName........ from DPISTAFF2008_2009 where name='George'
union
select LastName........ from DPISTAFF2009_2010 where name='George'

Wenn Sie eine solche Abfrage wiederholt auslösen müssen und über große Datenbanken verfügen, benötigen Sie eine komplexere Lösung.

1
JR ibkr 19 Apr. 2018 im 17:03

Anscheinend haben mehrere Tabellen denselben Spaltennamen. Sie sollten den Tabellennamen oder den Tabellenaliasnamen vor jeder Spalte in der select-Klausel als verwenden

Tablename.columnname
0
crack_iT 19 Apr. 2018 im 16:59