[英]SQL Joins . One to many relationship
我有两个表如下
Table 1 ----------------------------------- UserID | UserName | Age | Salary ----------------------------------- 1 | foo | 22 | 33000 -----------------------------------
Table 2 ------------------------------------------------ UserID | Age | Salary | CreatedDate ------------------------------------------------ 1 | NULL | 35000 | 2015-01-01 ------------------------------------------------ 1 | 28 | NULL | 2015-02-01 ------------------------------------------------ 1 | NULL | 28000 | 2015-03-01 ------------------------------------------------
我需要这样的结果。
Result ----------------------------------- UserID | UserName | Age | Salary ----------------------------------- 1 | foo | 28 | 28000 -----------------------------------
这只是一个例子。 在我的真实项目中,上表中大约有6列,例如“年龄”和“薪水”。
在表2中,每条记录仅具有一个值,即,如果Age具有值,则Salary将为NULL,反之亦然。
更新:
表2具有CreatedDate列。 因此,我想获取最新的“ NOTNULL” CELL值而不是最大值。
您可以使用简单的MAX()
和GROUP BY
完成此操作:
select t1.userid,t1.username, MAX(t2.Age) as Age, MAX(t2.Salary) as Salary
from table1 t1 join
table2 t2 on t1.userid=t2.userid
group by t1.userid,t1.username
结果:
userid username Age Salary
--------------------------------
1 foo 28 35000
SQL Fiddle中的样本结果
注意:我给您带来的好处是,您不必知道自己在做什么,而只是没有告诉我们有关架构的所有信息。
看起来Table 2
实际上是一个“更新”表,其中每一行都包含要应用于Table 1
的基本实体的更改增量。 在这种情况下,您可以使用关联的联接(技术上是外部应用程序)检索每列的数据,并将结果放在一起。 类似于以下内容:
select a.UserID, a.UserName,
coalesce(aAge.Age, a.Age),
coalesce(aSalary.Salary, a.Salary)
from [Table 1] a
outer apply (
select Age
from [Table 2] x
where x.UserID = a.UserID
and x.Age is not null
and not exists (
select 1
from [Table 2] y
where x.UserID = y.UserID
and y.Id > x.Id
and y.Age is not null
)
) aAge,
outer apply (
select Salary
from [Table 2] x
where x.UserID = a.UserID
and x.Salary is not null
and not exists (
select 1
from [Table 2] y
where x.UserID = y.UserID
and y.Id > x.Id
and y.Salary is not null
)
) aSalary
请注意,我假设您至少有一个Table 2
的Id
列,该列随每个插入而单调增加。 如果您有“更改时间”列,请改用它来获取最新行,因为这样更好。
要获取基于CreatedDate
的最新值,可以使用ROW_NUMBER
筛选最新行。 这里的分区基于UserID
,其他列为Age
和Salary
。
;WITH Cte AS(
SELECT
UserID,
Age = MAX(Age),
Salary = MAX(Salary)
FROM(
SELECT *, Rn = ROW_NUMBER() OVER(
PARTITION BY
UserID,
CASE
WHEN Age IS NOT NULL THEN 1
WHEN Salary IS NOT NULL THEN 2
END
ORDER BY CreatedDate DESC
)
FROM Table2
)t
WHERE Rn = 1
GROUP BY UserID
)
SELECT
t.UserID,
t.UserName,
Age = ISNULL(c.Age, t.Age),
Salary = ISNULL(c.Salary, t.Salary)
FROM Table1 t
LEFT JOIN Cte c
ON t.UserID = c.UserID
以下查询应该工作(在MSSQL中可以正常工作):
select a.userID,a.username,b.age,b.sal from <table1> a
inner join
(select userID,MAX(age) age,MAX(sal) sal from <table2> group by userID) b
on a.userID=b.userID
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.