我正在运行MS SQL-Server-2016我试图从分区为ParentId的表中获取第一个值。我有这样的数据集:
CREATE TABLE #TempTable
(
PTORequestDetailId INT,
PTORequestId INT,
DivisionPTOAccrualId INT,
RequestDate DATE,
StartTime DateTime,
Hours Decimal(19,2),
ResponseNotes nvarchar(500),
Status int,
CreatedOn DateTime,
ModifiedOn DateTime
)
INSERT INTO #TempTable
SELECT 60, 48, 139, '2015-09-09', '2015-09-08 20:00:00.000', 8.00,'',0, '2015-09-09 13:30:40.363', '2015-09-09 13:30:40.313' UNION
SELECT 61, 48, 139, '2015-09-10', '2015-09-09 20:00:00.000', 8.00,'',0, '2015-09-09 13:30:40.363', '2015-09-09 13:30:40.313' UNION
SELECT 62, 48, 139, '2015-09-11', '2015-09-10 20:00:00.000', 8.00,'',0, '2015-09-09 13:30:40.363', '2015-09-09 13:30:40.313' UNION
SELECT 63, 48, 139, '2015-09-13', '2015-09-12 20:00:00.000', 8.00,'',0, '2015-09-09 13:30:40.363', '2015-09-09 13:30:40.313' UNION
CREATE TABLE #TempParent
(
PTORequestId INT,
)
INSERT INTO #TempParent
SELECT 48
运行此命令将创建一个临时表,其中包含我正在使用的数据集。 我试图获得由#TempTable.PTORequestId划分的DivisionPTOAccrualId的第一个值,
SELECT #TempParent.*, AccrualDetails.*
FROM #TempParent
CROSS APPLY (
SELECT FIRST_VALUE(#TempTable.DivisionPTOAccrualId)
OVER (PARTITION BY #TempTable.PTORequestId
ORDER BY #TempTable.PTORequestDetailId ASC
ROWS UNBOUNDED PRECEDING
) as AccrualId
FROM #TempTable
WHERE #TempTable.PTORequestId = #TempParent.PTORequestId
) as AccrualDetails
我基本上试图从我的父级每行获取一次139
,但FIRST_VALUE似乎会返回多个结果,因此它会创建笛卡尔积。
因此,而不是获得单行结果集
PTORequestId:48 AccrualId:139
First Value应该只返回一个Value 然而它回归了4个价值观。 为什么会发生这种情况,如何使FIRST_VALUE每行返回一个值?
修改
我认为这是因为我从TempTable中选择了FIRST_VALUE,所以它选择Temp Table中每行的First Value。但实际上我只做过一次
对于任何需要澄清我做错事的人。 我期待我的分区在我的表中过滤行。 我假设因为表上的SUM将返回整个表的总和而不是每行的整个表的SUM。该总和工作基于分区数据,而不是这种情况。
答案 0 :(得分:2)
我不确定是否使用First_Value()
进行此操作,但我发现使用Row_Number()
更容易,并且只获取第一条记录:
;With Cte As
(
Select T.*,
Row_Number() Over (Partition By T.PTORequestId Order By T.PTORequestDetailId) As RN
From #TempTable T
Join #TempParent P On P.PTORequestId = T.PTORequestId
)
Select PTORequestId, DivisionPTOAccrualId As AccruralId
From Cte
Where RN = 1