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.
3 Antworten
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.
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.
Anscheinend haben mehrere Tabellen denselben Spaltennamen. Sie sollten den Tabellennamen oder den Tabellenaliasnamen vor jeder Spalte in der select-Klausel als verwenden
Tablename.columnname
Neue Fragen
sql
Structured Query Language (SQL) ist eine Sprache zum Abfragen von Datenbanken. Zu den Fragen sollten Codebeispiele, Tabellenstruktur, Beispieldaten und ein Tag für die verwendete DBMS-Implementierung (z. B. MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 usw.) gehören. Wenn sich Ihre Frage ausschließlich auf ein bestimmtes DBMS bezieht (bestimmte Erweiterungen / Funktionen verwendet), verwenden Sie stattdessen das Tag dieses DBMS. Antworten auf mit SQL gekennzeichnete Fragen sollten ISO / IEC-Standard-SQL verwenden.