SQL 从 Table 获取第一个值
SQL Get First Value From Table
我是 运行 MS SQL-Server-2016 我正在尝试从 table 分区的 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
运行 这将使用我正在处理的数据集创建一个临时文件 table。
我正在尝试获取由 #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
我基本上是尝试从我的 Parent 中每行获取一次 139
,但是 FIRST_VALUE 似乎 return 多个结果,因此它创建了笛卡尔积.
所以不是获取单行结果集
PTORequestId: 48
应计 ID:139
第一个值只能 return 一个值
然而它的 returning 4 值。
为什么会发生这种情况,如何使 FIRST_VALUE return 每行一个值?
编辑
我认为发生这种情况是因为我从 TempTable 中选择了 FIRST_VALUE,所以它正在为 Temp Table 中的每一行选择第一个值。但我其实只做了一次
对于任何需要澄清我做错了什么的人。
我期待我的 Table 中的分区过滤行。
我假设 Table 上的 SUM 将 Return 整个 table 的总和,而不是整个 Table 每行的总和。该求和工作基于分区数据,但事实并非如此。
我不确定用 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
我是 运行 MS SQL-Server-2016 我正在尝试从 table 分区的 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
运行 这将使用我正在处理的数据集创建一个临时文件 table。 我正在尝试获取由 #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
我基本上是尝试从我的 Parent 中每行获取一次 139
,但是 FIRST_VALUE 似乎 return 多个结果,因此它创建了笛卡尔积.
所以不是获取单行结果集
PTORequestId: 48 应计 ID:139
第一个值只能 return 一个值 然而它的 returning 4 值。 为什么会发生这种情况,如何使 FIRST_VALUE return 每行一个值?
编辑
我认为发生这种情况是因为我从 TempTable 中选择了 FIRST_VALUE,所以它正在为 Temp Table 中的每一行选择第一个值。但我其实只做了一次
对于任何需要澄清我做错了什么的人。 我期待我的 Table 中的分区过滤行。 我假设 Table 上的 SUM 将 Return 整个 table 的总和,而不是整个 Table 每行的总和。该求和工作基于分区数据,但事实并非如此。
我不确定用 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