使用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时对您有很大帮助。干杯,基思。我去看看。