然而,在Get top 1 row of each group的情况下也提出了类似的问题,在这种情况下,没有WHERE条件改变预期输出.所以我的案子是这样的.
假设我们有以下数据表,我在下面的SQL查询中临时生成并填充了它.我想要的是找到给定名称的第一个周期记录,忽略末尾的WHERE子句.有一个按照日期戳顺序排列的循环栏.请注意,每个名称的周期编号不一定从1开始.因此,对于每个名称,我想知道基于日期戳和周期编号的哪个记录代表第一个周期,因为具有相同时间戳的多个记录可能具有不同的周期编号;在这种情况下,最早的记录是具有较小周期编号的记录.
CREATE TABLE temp_table
(
Id INT,
Cycle INT,
DateStamp DateTime2,
Name VARCHAR(255)
);
INSERT INTO temp_table (id, Cycle, DateStamp, Name)
VALUES (1, 4, '2024-01-10T17:53:12', 'John'),
(2, 5, '2024-01-10T17:53:14', 'John'),
(3, 3, '2024-01-10T17:53:10', 'John'),
(4, 7, '2024-01-10T17:53:14', 'John'),
(5, 2, '2024-01-10T17:53:10', 'John'),
(6, 2, '2024-01-10T17:53:11', 'George'),
(7, 1, '2024-01-10T17:53:11', 'George'),
(8, 4, '2024-01-10T17:53:13', 'George'),
(9, 3, '2024-01-10T17:53:12', 'George'),
(10, 7, '2024-01-10T17:53:11', 'Tom'),
(11, 4, '2024-01-10T17:53:10', 'Tom'),
(12, 8, '2024-01-10T17:53:12', 'Tom'),
(13, 3, '2024-01-10T17:53:10', 'Tom'),
(14, 5, '2024-01-10T17:53:11', 'Tom'),
(15, 6, '2024-01-10T17:53:11', 'Tom'),
(16, 9, '2024-01-10T17:53:12', 'Tom');
SELECT * FROM temp_table;
SELECT
*,
CASE
WHEN FIRST_VALUE(Id) OVER (PARTITION BY Name ORDER BY DateStamp, Cycle) = Id
THEN 1
ELSE 0
END AS IsFirstCycle
FROM
temp_table
WHERE
Name = 'Tom' --AND Id >= 14
DROP TABLE temp_table;
一切都运行得很好,上面的查询根据日期和周期编号清楚地指出每个名称分区的哪个记录代表初始周期.在上面的例子中,我进行了过滤,只看到Tom的最终结果记录.
查看结果的屏幕截图:
然而,我的问题是,当我取消注释并添加另一个条件以按记录ID筛选最终结果时(在上面的示例中为14),我仍然得到一个被标记为该子分区的第一个周期的记录.
但我期望也希望看到的是,该子分区中没有记录是初始的第一个周期,因为我的第一个周期记录是整个分区上的记录,忽略了整个查询的WHERE
子句.
据我在网上的阅读和理解,以上条款应该是WHERE条款不可知的.当然,我希望在最后按WHERE子句进行筛选,并且只显示ID超过任何数字的记录,但是当我需要检测记录是否是第一个周期时,我不想考虑子集,而是考虑整个表中的完整分区,而忽略任何WHERE条件.请指导我如何实现这一点,因为OVER子句清楚地首先根据ID&>14条件过滤分区记录,然后应用OVER子句来检测和标记该分区内的第一个周期记录.我的预期是返回第二个图像中的三个记录,其中所有记录的IsFirstCycle都被标记为0,因为Tom分区中唯一的第一个周期记录是ID=13的记录,如第一个屏幕截图所示.