【发布时间】:2020-01-24 19:48:19
【问题描述】:
代码(示例数据暂存):
DECLARE @Emp TABLE
(
[EId] INT IDENTITY(1, 1)
, [FN] NVARCHAR(50)
, [LN] NVARCHAR(50)
) ;
DECLARE @EmpPhCont TABLE
(
[EId] INT
, [PhType] VARCHAR(10)
, [PhNum] VARCHAR(16)
, [PhExt] VARCHAR(10)
, [IsMain] BIT
, [CreatedOn] DATETIME
) ;
INSERT INTO @Emp
VALUES
( N'Emp1', N'Emp1' )
, ( N'Emp2', N'Emp2' )
, ( N'Emp3', N'Emp3' )
, ( N'Emp4', N'Emp4' )
, ( N'Emp5', N'Emp5' )
, ( N'Emp6', N'Emp5' ) ;
INSERT INTO @EmpPhCont
VALUES
( 1, 'Home', '111111111', NULL, 0, '2020-01-01 00:00:01' )
, ( 1, 'Mobile', '222222222', NULL, 1, '2020-01-01 00:00:02' )
, ( 1, 'Work', '333333333', NULL, 0, '2020-01-01 00:00:03' )
, ( 2, 'Work', '444444444', '567', 1, '2020-01-01 00:00:04' )
, ( 2, 'Mobile', '555555555', NULL, 0, '2020-01-01 00:00:05' )
, ( 2, 'Mobile', '454545454', NULL, 0, '2020-01-01 00:00:06' )
, ( 3, 'Home', '777777777', NULL, 0, '2020-01-01 00:00:07' )
, ( 3, 'Mobile', '888888888', NULL, 1, '2020-01-01 00:00:08' )
, ( 3, 'Mobile', '12121212', NULL, 0, '2020-01-01 00:00:09' )
, ( 4, 'Work', '101010101', '111', 1, '2020-01-01 00:00:10' )
, ( 4, 'Work', '101010102', '232', 0, '2020-01-01 00:00:11' )
, ( 5, 'Work', '545454545', '456', 0, '2020-01-01 00:00:10' )
, ( 5, 'Work', '456456456', NULL, 1, '2020-01-01 00:00:11' ) ;
说明:
@Emp 是示例员工表(唯一员工记录)。
- EId = 员工 ID
- FN = 名字
- LN = 姓氏
@EmpPhCont 是示例 Employee Phone Contact 表(@Emp 表中的每个 Emp 在此处可以有零个、一个或多个电话号码 - 根据 Emp/Type 是唯一的)。
- PhType = 电话类型(家庭、手机、工作等)
- PhNum = 电话号码
- PhExt = 电话分机(主要适用于“工作”PhType)
- IsMain = 是否为主要联系人号码。每个拥有电话号码的员工都将有 1 条记录标记为 IsMain。
- CreatedOn = 创建记录的日期
目标:
使用以下列为每位员工输出 1 条记录
EID |主页号码 |手机号码 |工作编号 | WorkNumExt | MainPhType
规则:
返回来自@Emp 的所有记录的所有EId,无论它们是否有@EmpPhCont 记录。
对于每个拥有@EmpPhCont 记录的emp,返回对应PhType 的最新创建的PhNum 和PhExt,除非同一Emp/PhType 的旧记录被标记为IsMain = 1(对于任何 emp,对于任何 PhType,如果 IsMain = 1,则始终返回 PhNum 和 PhExt 值)。
预期输出:
EId HomeNum MobileNum WorkNum WorkNumExt MainPhType
1 111111111 222222222 333333333 NULL Mobile
2 NULL 454545454 444444444 567 Work
3 777777777 888888888 NULL NULL Mobile
4 NULL NULL 101010102 111 Work
5 NULL NULL 456456456 NULL Work
6 NULL NULL NULL NULL NULL
我的失败尝试:
SELECT [EM].[EId]
, MAX ( IIF([PH].[PhType] = 'Home', [PH].[PhNum], NULL)) AS [HomePhNum]
, MAX ( IIF([PH].[PhType] = 'Mobile', [PH].[PhNum], NULL)) AS [MobilePhNum]
, MAX ( IIF([PH].[PhType] = 'Work', [PH].[PhNum], NULL)) AS [WorkPhNum]
FROM @Emp AS [EM]
LEFT JOIN @EmpPhCont AS [PH]
ON [EM].[EId] = [PH].[EId]
GROUP BY [EM].[EId] ;
【问题讨论】:
-
EId 3 为什么只能得到一个手机号码?为什么你得到你所做的那个的逻辑是什么?我认为您需要先查看 ROW_NUMBER,以便您可以获得每个 EId 和 PhoneType 的正确行...提示(PARTITION BY)
-
@SeanLange Question 已经说明了这个规则:"返回 newest 为相应的 PhType 创建的 PhNum 和 PhExt,UNLESS相同 Emp/PhType 的旧记录被标记为 IsMain = 1"
-
@Andreas 哎呀错过了。 :P
标签: sql sql-server tsql sql-server-2016