合并 SQL 中多个表的记录

Combining records from multiple tables in SQL

我目前有以下 SQL 查询:

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'

有多个 table,每个年份的信息类型相同。我想从每个 table 中检索与 WHERE 信息匹配的所有记录。假设 George 是独一无二的,那将是每个 table 的 1 个条目,因此我可以比较他每年的信息。

即使我在我的 WHERE 语句中添加了一个 table ID,我还是得到了 "ambigious_column_error"。我还需要添加什么才能使这项工作正常进行吗?

更新查询: 我试过了,看看它是否有效。在这里我只有 2 个 table 而不是全部 6 个,所以我可以在完成所有工作之前尝试让它工作(并且可能我会在实现它时使用变量以便我可以轻松更改名称)。它没有。我得到 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;

如果我只从一个没有 UNION ALL 的 table 中执行一次,则查询成功 returns 来自 table 的 1 条记录。

因为您的 table 模式不是很好(这些应该都是 1 table 与 'Year' 列相结合),您将不得不做一个大联合:

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'

更新以更多地讨论架构。

一个更好的架构,可以加快 select 处理此数据的速度,并大大降低此 sql 的复杂性,数据类似于:

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)
);

然后您可以在 firstname 上创建一个索引,以便非常快速地 selection 针对特定的人。

CREATE INDEX dpistaff_firstname ON dpistaff (firstname);

现在您的查询是:

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

如果你发现你经常select年,比如"give me everyone for 2008"那么你也可以添加一个记录年的索引。如果您经常同时为这两个 select ,例如 "give me Bill's data for 2016"

,您也可能(或替代地)想要 (recordYear, FirstName) 上的索引

如果您的 RDBMS 支持分区,您可以考虑在记录年上创建分区而不是索引。尽管您使用的是 sqlLite,但我根据您的语法猜测,因此此处的索引必须足够。另外,您的数据非常小,因此分区方案可能有点矫枉过正。

这里最大的收获是,如果您发现自己不得不经常创建一个新的 table,或者只是因为我们在一个新的 month/quarter/year 中而添加列,那么您的架构可能不太好.我们的目标是一次构建架构,然后使用多年。添加新对象时只添加新对象(数据库、tables、列)。在这种情况下,一个新的 table 用于存储 "School" 的属性,例如 SchoolAddressSchoolPhone。然后可能稍后添加一个 table 来存储 ClassRooms 和它的属性。

似乎多个 table 具有相同的列名,您应该在 select 子句中的每列之前使用 table 名称或 table 别名 as

Tablename.columnname

所有 DPISTAFF 表都有相同的列。我建议创建一个将名称作为输入的过程。

在过程中使用以下内容:

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

如果您必须反复触发此类查询并且您拥有庞大的数据库,那么您需要更复杂的解决方案。