合并 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" 的属性,例如 SchoolAddress
、SchoolPhone
。然后可能稍后添加一个 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'
如果您必须反复触发此类查询并且您拥有庞大的数据库,那么您需要更复杂的解决方案。
我目前有以下 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" 的属性,例如 SchoolAddress
、SchoolPhone
。然后可能稍后添加一个 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'
如果您必须反复触发此类查询并且您拥有庞大的数据库,那么您需要更复杂的解决方案。