如何在SQL中连接六个表而只包含某些行?

时间:2018-01-20 01:41:10

标签: sql sql-server join

我有6个人对应6个日历年的数据,2010-2015。每个表中的每一行都有一个唯一的变量id,对应于参与全年的个人,每个表的变量年份设置为参与年份。

如果一个人整年都没有参与,那么该表中没有相应的行。

例如,

enyear2010

id year (other variables)

0000001 2010 .

0000002 2010 .

000003 2010 .

0000004 2010 .

enyear2011

id year (other variables)

0000002 2011 .

0000003 2011 .

0000004 2011 .

0000005 2011 .

enyear2012

id year (other variables)

0000001 2012 .

0000002 2012 .

0000003 2012 .

0000005 2012 .

在身份1的情况下,他们并没有参加2011年的全部比赛,但确实在2012年重返赛场,2012年的比赛结果为4分,2011年的比赛分别为5分。

我想将所有这些表连接在一起并获取至少连续2年出现的行(对于id 1,它们不会出现在此连接表中),并创建一个对应于一个人在数据集中的年数以及该人何时开始。

merged-table
id startyear enrolledyears (other variables)
0000002 2010      3             .
0000003 2010      3             .
0000004 2010      2             .
0000005 2011      2             .

到目前为止,我能够将其概念化为一系列左连接,这样每个表中的年变量成为初始变量,但我认为当有人在2010年进入时,该过程会崩溃。

非常感谢任何建议!

2 个答案:

答案 0 :(得分:2)

首先,将事物分成年度命名表并不是一个好的表设计。你应该把所有东西放在同一个表中。现在,每年添加的内容都需要添加到您提供的任何SQL中。

你可以让它看起来像这样一个表:

SELECT ID, Year FROM entear2010 
  UNION ALL
SELECT ID, Year FROM entear2011 
  UNION ALL
SELECT ID, Year FROM entear2012

现在您可以使用该构造来获得您想要的内容。你把它放进一个叫做CTE的东西:

WITH AllData AS (
SELECT ID, Year FROM entear2010 
  UNION ALL
SELECT ID, Year FROM entear2011 
  UNION ALL
SELECT ID, Year FROM entear2012
)

SELECT * FROM AllData

现在你可以'自我加入'来检查一个id是否也在上一年:

WITH AllData AS (
SELECT ID, Year FROM entear2010 
  UNION ALL
SELECT ID, Year FROM entear2011 
  UNION ALL
SELECT ID, Year FROM entear2012
)
SELECT Current.ID, Current.Year 
FROM AllData As Current
INNER JOIN AllData As Prior
ON  Current.ID = Prior.ID
AND Current.Year-1 = Prior.Year

这会让你连续两年获得人员名单。现在你只是总结一下:

WITH AllData AS (
SELECT ID, Year FROM entear2010 
  UNION ALL
SELECT ID, Year FROM entear2011 
  UNION ALL
SELECT ID, Year FROM entear2012
)

SELECT ID, COUNT(*) YearsEnrolled, MIN(Year) As StartYear
FROM AllData
WHERE ID IN (
  SELECT DISTINCT Current.ID
  FROM AllData As Current
  INNER JOIN AllData As Prior
  ON  Current.ID = Prior.ID
  AND Current.Year-1 = Prior.Year
  )
GROUP BY ID

我认为这就是你所追求的目标。

使用窗口函数可能有一种更聪明的方法......但其他人无疑会发布它。

答案 1 :(得分:2)

您必须首先合并所有表(通过union all或创建临时表),然后在SQL下面运行:

select * from (
select MEMBER_ID, max(YEAR_NUM) MAX_YEAR, MIN(YEAR_NUM) MIN_YEAR, COUNT(YEAR_NUM) YEAR_COUNT
from merged_tables
group by MEMBER_ID) w1
where MAX_YEAR=MIN_YEAR+YEAR_COUNT-1 and YEAR_COUNT>1

以上SQL将返回连续注册年份大于一年的所有成员ID。