sql-server - MSSQL - 需要将多条记录查询到一条记录/一组结果中 - 基于 Id 和 Date
问题描述
**更新标题..
首先也是最重要的:我知道这听起来像是一个重复的问题,但我从昨天下午开始就在网上搜索解决方案。
我有 2 张桌子,这是我的测试资料:
create table #UserMaster
(
UserId int identity(1,1),
FirstName varchar(50),
LastName varchar(50),
Department smallint,
JobCode varchar(8),
);
create table #UserUpdateInfoMain
(
Id int identity(1,1),
UserId int,
DateRequested smalldatetime,
SubmittedBy varchar(20),
RequestedBy varchar(20),
NameChange varchar(50),
TransferDept smallint,
TransferJob varchar(8),
TerminationDate date
);
我们的人力资源部门将提交更改员工姓名的请求、调动请求(针对工作或部门)以及终止请求。此表 (UserUpdatedInfoMain) 背后的想法是容纳所有此类请求,并将它们与主要用户信息(在 UserMaster 中)适当地链接起来。因此,当我们在数据库中搜索用户时,我们的想法是能够看到他们当前的姓氏、当前的部门/工作分配,或者如果他们已经被终止 - 也能够看到所有的线索这样的变化是一个加号。
Bob 将收到一个更改姓名的请求。一周后 Bob 可能会更换职位,因此会收到部门调动请求。我正在尝试进行查询以查看:Bob -> NewName -> NewDept(一条记录,而不是多个记录)
它的诀窍是可能有多个名称更改和转移,因此我需要获取每个名称中的最新名称以显示在查询中。我发现了一些有点相似的东西,我似乎无法开始工作(包括使用 min/max - 如果它只是寻找一个结果,效果很好),我设法得到了一次结果另一行出现在某一点,只是无法丢弃所有不必要的结果。
这是我正在使用的示例数据:
插入#UserMaster(名字,姓氏,部门,工作代码) 值('约翰','史密斯',1212,'A1234'),--1 ('詹姆斯','托德',1232,'B2345'),--2 ('斯蒂芬','威廉姆斯',1212,'A1234'),--3 ('凯西','贝茨',1212,'C2342'),--4 ('Rob','Johnson',3434,'A1234'),--5 ('Cindy','Lou',2314,'A1234'), ('杰西','日期',2323,'D3422'), ('苹果','苹果酒',1342,'B2312'), ('百事可乐','可乐',1432,'A1234'), ('随机','鲍勃',1342,'C3421'), ('绿巨人','霍根',3422,'C3221'), ('约翰','Cena',3432,'B2231'), ('萨沙','班克斯',2321,'B2312'), ('Jimmy','Iovine',3432,'A1234'), ('Dwayne','约翰逊',1325,'C2342'), ('悉尼','皮尔斯',1241,'A1234'), ('Expo','Marks',4321,'B2312'), ('Pat','Swizzle',2521,'C2342'), ('猴子','骨头',1212,'D3422'), ('快乐','吉尔摩',4545,'D3422'); 插入#UserUpdateInfoMain(UserId、DateRequested、SubmittedBy、RequestedBy、NameChange、TransferDept、TransferJob、TerminationDate) 值 (1, cast(getdate()-5 as smalldatetime), 'rob', 'bob', 'Waters1', NULL, NULL, NULL), (2, cast(getdate()-4 as smalldatetime), 'rob', 'bob', NULL, 7878, 'J7098', NULL), (3, cast(getdate()-3 as smalldatetime), 'rob', 'bob', 'Cider1', NULL, NULL, NULL), (4, cast(getdate()-4 as smalldatetime), 'rob', 'bob', NULL, NULL, NULL, cast(getdate()-3 as date)), (5, cast(getdate()-2 as smalldatetime), 'rob', 'bob', NULL, 9898, NULL, NULL), (1, cast(getdate()-3 as smalldatetime), 'jim', 'bob', 'Lakely2', NULL, NULL, NULL), (1, cast(getdate() as smalldatetime), 'sue', 'bob', 'Salsa3', NULL, NULL, NULL), (1, cast(getdate() as smalldatetime), 'sue', 'bob', NULL, 9648, 'K9487', NULL), (2, cast(getdate()-1 as smalldatetime),'rosco', 'bob', 'Mordor1', NULL, NULL, NULL), (2, cast(getdate() as smalldatetime), 'rosco', 'bob', 'Elves2', NULL, NULL, NULL);
最终应该出现的两个示例如下所示......当然,其他 3 个也应该出现
(#UserUpdateInfoMain)
UserId NameChange TransferDept TransferJob TerminationDate
1 Salsa3 9648 K9487 NULL
2 Elves2 9343 H8898 NULL
为冗长的帖子道歉,我只是想确保我能体面地解释事情,并有一个我正在玩的工作示例。我也很抱歉没有为我查看和完成的所有内容提供链接/示例。
我尝试在每列上进行最大日期的 CTE 并将其与 #UserUpdatedInfoMain 表连接起来,但这并没有完全奏效;我无法找到正确的组合来让它们正常工作。
例子:
theNameChanged_cte (UserId, Req_Date)
as
(
select
i2.UserId,
max(i2.DateRequested) as Req_Date
from #UserUpdateInfoMain i2
group by i2.UserId
)
...or...
theNameChanged_cte (UserId, Req_Date, NameChange)
as
(
select
i2.UserId,
max(i2.DateRequested) as Req_Date,
i2.NameChange
from #UserUpdateInfoMain i2
group by i2.UserId, i2.NameChange
having i2.NameChange is not null
)
第一个合法的 CTE 只是查找给定 UserId 的最近日期 - 好的,很酷......这已经是中途了。第二个请求所有的 NameChange 请求,所以一些 UserId 出现了两次。如果我可以将 MAX 与 where 语句一起使用,我想我可以得到它。我想我的大脑在这一点上很不幸。
任何和所有的帮助、建议和建议 - 甚至是“查看这种类型的功能”都将不胜感激(实际的解决方案会更好!但我并没有接受建议并与他们合作)。我希望我在这篇文章中获得了所有必要的信息以获得帮助。
解决方案
这里有一个 SQL hack 给你:
DECLARE
@UserId INT, @NameChange VARCHAR(50), @TransferDept smallint, @TransferJob VARCHAR(8), @TerminationDate DATE
SET @UserId = 1;
SELECT
@NameChange = CASE WHEN @NameChange IS NULL THEN NameChange ELSE @NameChange END,
@TransferDept = CASE WHEN @TransferDept IS NULL THEN TransferDept ELSE @TransferDept END,
@TransferJob = CASE WHEN @TransferJob IS NULL THEN TransferJob ELSE @TransferJob END,
@TerminationDate = CASE WHEN @TerminationDate IS NULL THEN TerminationDate ELSE @TerminationDate END
FROM #UserUpdateInfoMain ui
WHERE
ui.UserId = @UserId
ORDER BY
ui.Id DESC;
SELECT
@UserId AS UserId,
@NameChange AS NameChange,
@TransferDept AS TransferDept,
@TransferJob AS TransferJob,
@TerminationDate AS TerminationDate;
退货
+--------+------------+--------------+-------------+-----------------+
| UserId | NameChange | TransferDept | TransferJob | TerminationDate |
+--------+------------+--------------+-------------+-----------------+
| 1 | Salsa3 | 9648 | K9487 | NULL |
+--------+------------+--------------+-------------+-----------------+
推荐阅读
- java - 在 Java Web 应用程序中 - 使用 Jxls 导出 Excel 时出现问题
- mysql - 将中文本转换为日期
- java - E/LoadedApk:无法使用 gradle:3.6.0 实例化 appComponentFactory
- quarkus - 如何配置 Quarkus 日志级别?
- android - Android Emulator 在高于 28 的 Api 上崩溃
- sql-server - 术语“Get-SqlErrorLog”未被识别为 cmdlet [Powershell] [SQL Server] 的名称
- javascript - 从 Firestore 格式化 JSON 数据
- excel - 3列之间的天数总和
- android - LiveData 更改不调用观察者
- java - 如何避免使用具有目标类型 List 的 Spring ConversionService 进行强制转换
?