使用SQL基于B列提取A列中某项的第一次出现
我有以下数据,我想创建一个结果集,其中包括使用SQL基于B列提取A列中某项的第一次出现,sql,sql-server,Sql,Sql Server,我有以下数据,我想创建一个结果集,其中包括项中的更改行以及code==1的第一个出现行。请注意,在项中的一个更改后看到的第一个代码并不总是必须为1(请参见*): 输入数据: DateTime Item Code *2016-12-02 16:34:00 1 1 2016-12-02 16:35:00 1 4 2016-12-02 16:36:00 1 1 2016-12-02 16:37:00
项
中的更改行以及code==1的第一个出现行。请注意,在项
中的一个更改后看到的第一个代码
并不总是必须为1(请参见*):
输入数据:
DateTime Item Code
*2016-12-02 16:34:00 1 1
2016-12-02 16:35:00 1 4
2016-12-02 16:36:00 1 1
2016-12-02 16:37:00 1 1
2016-12-02 16:38:00 1 7
2016-12-02 16:39:00 1 5
2016-12-02 16:40:00 1 6
2016-12-02 16:41:00 2 5
*2016-12-02 16:42:00 2 1
2016-12-02 16:43:00 2 4
2016-12-02 16:44:00 2 1
2016-12-02 16:45:00 2 5
2016-12-02 16:46:00 2 8
2016-12-02 16:47:00 2 1
2016-12-02 16:48:00 5 7
2016-12-02 16:49:00 5 7
*2016-12-02 16:50:00 5 1
2016-12-02 16:51:00 5 1
2016-12-02 16:52:00 5 4
2016-12-02 16:53:00 5 3
*2016-12-02 16:54:00 1 1
2016-12-02 16:55:00 1 1
2016-12-02 16:56:00 1 1
2016-12-02 16:57:00 1 8
2016-12-02 16:58:00 1 9
2016-12-02 16:59:00 1 3
2016-12-02 17:00:00 1 2
2016-12-02 17:01:00 1 4
日期时间项目代码
*2016-12-02 16:34:00 1 1
2016-12-02 16:35:00 1 4
2016-12-02 16:36:00 1 1
2016-12-02 16:37:00 1 1
2016-12-02 16:38:00 1 7
2016-12-02 16:39:00 1 5
2016-12-02 16:40:00 1 6
2016-12-02 16:41:00 2 5
*2016-12-02 16:42:00 2 1
2016-12-02 16:43:00 2 4
2016-12-02 16:44:00 2 1
2016-12-02 16:45:00 2 5
2016-12-02 16:46:00 2 8
2016-12-02 16:47:00 2 1
2016-12-02 16:48:00 5 7
2016-12-02 16:49:00 5 7
*2016-12-02 16:50:00 5 1
2016-12-02 16:51:00 5 1
2016-12-02 16:52:00 5 4
2016-12-02 16:53:00 5 3
*2016-12-02 16:54:00 1 1
2016-12-02 16:55:00 1 1
2016-12-02 16:56:00 1 1
2016-12-02 16:57:00 1 8
2016-12-02 16:58:00 1 9
2016-12-02 16:59:00 1 3
2016-12-02 17:00:00 1 2
2016-12-02 17:01:00 1 4
预期产出数据:
DateTime Item Code
*2016-12-02 16:34:00 1 1
*2016-12-02 16:42:00 2 1
*2016-12-02 16:50:00 5 1
*2016-12-02 16:54:00 1 1
日期时间项目代码
*2016-12-02 16:34:00 1 1
*2016-12-02 16:42:00 2 1
*2016-12-02 16:50:00 5 1
*2016-12-02 16:54:00 1 1
我正在使用SQL Server 2012 Express。如果有人推荐一个很好的参考来学习这些东西,那也太好了。你可以使用行数的差来确定项的值在哪里发生了变化,然后再从中选择另一个行数
来获得第一个code=1
:
WITH cte AS (
SELECT
[DateTime]
, Item
, Code
, ROW_NUMBER() OVER (PARTITION BY Item ORDER BY [DateTime]) AS RowNum
)
SELECT
[DateTime]
, Item
, Code
FROM
cte
WHERE
RowNum = 1
AND Code = 1;
WITH CteGrp AS(
SELECT *,
grp = ROW_NUMBER() OVER(ORDER BY Datetime) -
ROW_NUMBER() OVER(PARTITION BY Item ORDER BY Datetime)
FROM #Tbl
),
Cte AS(
SELECT *,
rn = ROW_NUMBER() OVER(PARTITION BY Item, grp ORDER BY Code, Datetime)
FROM CteGrp
)
SELECT
Datetime, Item, Code
FROM Cte
WHERE rn = 1
ORDER BY Datetime;
第一个CTE是将连续日期的岛屿分组的常见解决方案。以下是Jeff Moden的一篇文章,以供解释:
试试这个
select min( dateTime) dateTime, item, code from (
select dateTime, item, code from theTableName where code = 1
) code_1s
group by item, code
编辑
获取新序列已开始的项目的每个实例。。代码=1是新序列实例的标志。。。这是一个带有where子句的简单select语句
select dateTime, item, code from theTableName where code = 1
code=1是重要的还是只是侥幸在您的预期输出中它们都是1?不,Keith,code==1是重要的,我会一直寻找表示记录开始的代码,因为项目中的新更改的第一个实例Code==1表示要处理的新记录。您可以在第二个cte中包含日期以计算行数。@vkp,您的意思是在code
之后的ORDER BY
中添加DateTime
?我应该提到,在项目更改后遇到的第一个代码可能不是1-我将使用数据来说明这一事实。谢谢。我将解构并检查每一位正在执行的操作,然后返回给您。如果我想检测到代码==4而不是代码==1,那么代码将不起作用,这是对的吗?Keith,我认为这只会为每个项的实例选择第一个代码实例-但是项在数据库中重复多次-例如,第6项将在一个月的不同时间重复20次,我想在每次遇到第6项的新实例时生成一个结果集行,而不是第一次。对不起,Keith,也许我没有很好地解释我自己。我需要在Item的每个实例中找到Code==1的第一次出现-因此,当Item更改时,我需要一个结果行,显示Code==1的第一次出现,当Item再次更改时,我需要显示Code==1的第一次出现,依此类推。Yes。我已经测试过了,效果很好。我不知道你是不是走了另一条路,基思,这就是我回到你身边的原因,但不管怎样,我非常感谢你的投入。谢谢,酷。在场景中通读乔·塞尔科的思想。这将在使用SQL时对您有很大帮助。干杯,基思。我去看看。