Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 自联接到组的最低发生率_Tsql_Sql Server 2008_Sql Order By_Self Join - Fatal编程技术网

Tsql 自联接到组的最低发生率

Tsql 自联接到组的最低发生率,tsql,sql-server-2008,sql-order-by,self-join,Tsql,Sql Server 2008,Sql Order By,Self Join,我发现T-SQL中有一个问题很难解决 我有一个包含记录组的表,按键1和键2分组。我按日期按时间顺序排列每组。对于每一条记录,我想看看在组中是否存在一条记录,该记录的日期较低,字段数据字段与当前记录的数据字段形成了允许的组合。对于允许的组合,我有一个名为AllowedCombinationsTable的表 我编写了以下代码来实现它: WITH Source AS ( SELECT key1, key2, datafield, date1, ROW_NUMBER() OVER

我发现T-SQL中有一个问题很难解决

我有一个包含记录组的表,按键1和键2分组。我按日期按时间顺序排列每组。对于每一条记录,我想看看在组中是否存在一条记录,该记录的日期较低,字段数据字段与当前记录的数据字段形成了允许的组合。对于允许的组合,我有一个名为AllowedCombinationsTable的表

我编写了以下代码来实现它:

WITH Source AS (
    SELECT key1, key2, datafield, date1,
        ROW_NUMBER() OVER(PARTITION BY key1, key2 ORDER BY date1 ASC) AS dateorder
        FROM table
)
SELECT L.key1, L.key2, L.datafield, DC.datafield2
FROM Source AS L
LEFT JOIN AllowedDataCombinationsTable DC
    ON D.datafield1 = L.datafield
LEFT JOIN Source AS R
    ON R.Key1 = L.Key1
    AND R.Key2 = L.Key2
    AND R.dateorder < L.dateorder
    AND DC.datafield2 = L.datafield
    -- AND "pick the one record with lowest dateorder"
允许组合稳定:

**Datafield1 Datafield**
Cat Sheep (and Sheep Cat)
Cat Horse (and Horse Cat)
Dog Horse (and Horse Dog)
加入后,我现在:

**Key1 Key2 Datafield Date DateOrder JoinedCombination JoinedCombinationDateOrder**
1 1 "Horse" 1-Jan-2010 1 NULL NULL
1 1 "Horse" 2-Jan-2010 2 NULL NULL
1 1 "Sheep" 3-Jan-2010 3 NULL NULL
1 1 "Dog" 4-Jan-2010 4 "Horse" 1
1 1 "Dog" 4-Jan-2010 4 "Horse" 2
1 1 "Cat" 5-Jan-2010 5 "Horse" 1
1 1 "Cat" 5-Jan-2010 5 "Horse" 2
1 1 "Cat" 5-Jan-2010 5 "Sheep" 3
我只想显示记录4狗的第一匹马,记录5猫的第一匹马


明白了吗

我认为如果没有设置用于测试查询的数据,这就可以了。检查注释的基本原理

WITH Source AS ( 
    SELECT key1, key2, datafield, date1, 
        ROW_NUMBER() OVER(PARTITION BY key1, key2 ORDER BY date1 ASC) AS dateorder 
        FROM table 
) 
SELECT L.key1, L.key2, L.datafield, DC.datafield2 
FROM Source AS L 
LEFT JOIN AllowedDataCombinationsTable DC 
    ON DC.datafield1 = L.datafield   --  DC Alias
LEFT JOIN Source AS R 
    ON R.Key1 = L.Key1 
    AND R.Key2 = L.Key2 
    AND DC.datafield2 = R.datafield   --  Changed alias from L to R
    AND R.dateorder = 1               --  Pick out lowest one
    AND R.dateorder < L.dateorder     --  Make sure it's not the same one
嗯,我不使用WITH或OVER,所以这是一种不同的方法。。我可能过于简化了一些东西,但在没有数据的情况下,我得出了以下结论:

SELECT distinct a.Key1, a.Key2, a.Datafield, 
       ISNULL(b.Datafield,'') as Datafield1, 
       ISNULL(b.Date,a.Date) as `Date`, 
       MIN(a.DateOrder) as DateOrder
FROM Source a
LEFT JOIN Source b 
     ON a.Key1 = b.Key1
     AND a.Key2 = b.Key2
     AND a.Dateorder <> b.Dateorder
LEFT JOIN AllowedDataCombinationsTable c
     ON a.Datafield = c.Datafield
     AND b.Datafield = c.Datafield1
GROUP BY a.Key1, a.Key2, a.Datafield, ISNULL(b.Datafield,''), ISNULL(b.Date,a.Date)

如果你能提供一个表/列列表,并更清楚地解释这些关系,我愿意写一个答案。好的,我添加了一些示例数据。L确实是一个打字错误。但这不起作用,因为R.dateorder=1不一定存在,它可能会被标准DC.datafield2=R.datafield.True过滤掉。然后,解决方法是将筛选条件连同必需的表联接一起移动到with子句中,以便只选择并排序有效的候选行,并在SELECT子句中使用RowNumber=1进行筛选。如果没有要测试的数据,很难编写正确的代码,所以我将此作为一个注释。每个人都在要求数据,但您建议使用什么作为传输数据的方便媒介?创建表语句虚拟表和列名很好,插入语句填充刚好足够的数据以提供有效的测试。你所列的看起来不错。谢谢,下次我会记住的。等我有时间的时候,我会把这个擦亮。正如我在另一个答案中所说,我现在解决了我的问题,在原始代码周围使用嵌套,并从中选择row_number=1,这与您的建议类似。在我们的服务器上,它可以在9秒内运行300000行,但我仍然认为可能有一种更快的方法。我想不起来了。嗨,谢谢。这很好,但我认为它在我的情况下也不起作用,因为我还有很多其他数据字段需要加入。我会测试一下,然后再给你回复。同时,我解决了这个问题,在我的原始代码周围使用了一个额外的嵌套行(row_number),以便在每个组中选择排名最高的加入行,这样就完成了任务,但在我看来效率很低。
SELECT distinct a.Key1, a.Key2, a.Datafield, 
       ISNULL(b.Datafield,'') as Datafield1, 
       ISNULL(b.Date,a.Date) as `Date`, 
       MIN(a.DateOrder) as DateOrder
FROM Source a
LEFT JOIN Source b 
     ON a.Key1 = b.Key1
     AND a.Key2 = b.Key2
     AND a.Dateorder <> b.Dateorder
LEFT JOIN AllowedDataCombinationsTable c
     ON a.Datafield = c.Datafield
     AND b.Datafield = c.Datafield1
GROUP BY a.Key1, a.Key2, a.Datafield, ISNULL(b.Datafield,''), ISNULL(b.Date,a.Date)