【问题标题】:Comparing 2 tables比较 2 个表
【发布时间】:2018-12-12 18:12:55
【问题描述】:

我有一个表,其中有所有 id,还有一个表,其中有 id,其中过程中有错误。我需要我的查询在错误发生之前选择最后 3 个 id。 例如:

first table:
id     |   info
___________________
100    |     1.0             
101    |     2.0                      
102    |     6.0             
103    |     9.0         
104    |     15.0         
105    |     8.0       
106    |     6.0
107    |     8.0       
108    |     6.0
109    |     8.0       
110    |     6.0



id of errors:

id        
____                                                              
104                 
110    

所以这个查询必须返回 id 的值: 109,108,107,103,102 和 101

提前致谢

【问题讨论】:

  • 到目前为止你有什么尝试???
  • "last" 由id定义?请记住,表没有记录顺序的概念。您需要根据数据排序。
  • 我尝试对 firsttable.id
  • 是的,他们都有分配给他们的个人 ID

标签: sql sql-server tsql sql-server-2008


【解决方案1】:
SELECT result.*
FROM errors e
CROSS APPLY (
    SELECT TOP 3 * 
    FROM [first table] ft 
    WHERE ft.id < e.id 
    ORDER BY ft.id DESC
) result

【讨论】:

  • 在我看来,当错误之间的差距小于或等于 3 时,这是不正确的:dbfiddle.uk/…
【解决方案2】:

这可能对你有用:

设置:

Create Table #Errs
(
Id Int
);

Insert Into #Errs Values
(104), (110)

Create Table #tbl
(
Id Int,
Info Decimal(6,2)
);

Insert Into #tbl Values
(100,1.0),
(101,2.0),
(102,6.0),
(103,9.0),
(104,15.0),
(105,8.0),
(106,6.0),
(107,8.0),
(108,6.0),
(109,8.0),
(110,6.0)

查询

With cte As
(
   Select 
      Id,
      LAG(Id,1,Null) OVER(Order By Id) As iderror1,
      LAG(Id,2,Null) OVER(Order By Id) As iderror2,
      LAG(Id,3,Null) OVER(Order By Id) As iderror3 
   From #tbl t
) 
Select iderror1 As ErrorList From cte Where Id In (Select Id From #Errs)
Union ALL
Select iderror2 As ErrorList From cte Where Id In (Select Id From #Errs)
Union ALL
Select iderror3 As ErrorList From cte Where Id In (Select Id From #Errs)
Order By ErrorList

如果您的 ID 不是按顺序排列的,您可以使用 (Select NULL) 如下:

With cte As
(
   Select 
      Id,
      LAG(Id,1,Null) OVER(Order By (Select NULL)) As iderror1,
      LAG(Id,2,Null) OVER(Order By (Select NULL)) As iderror2,
      LAG(Id,3,Null) OVER(Order By (Select NULL)) As iderror3 
   From #tbl t
) 
Select iderror1 As ErrorList From cte Where Id In (Select Id From #Errs)
Union ALL
Select iderror2 As ErrorList From cte Where Id In (Select Id From #Errs)
Union ALL
Select iderror3 As ErrorList From cte Where Id In (Select Id From #Errs)
Order By ErrorList

结果

ErrorList
--------
101
102
103
107
108
109

【讨论】:

    【解决方案3】:

    您可以使用窗口函数计算辅助组 SUM()ROW_NUMBER() 以获得最后 3 行:

    WITH cte AS (
      SELECT t1.*, -sub.c+ SUM(sub.c) OVER(ORDER BY t1.id) AS grp
      FROM t1
      LEFT JOIN t2
        ON t1.id = t2.id
      CROSS APPLY (SELECT CASE WHEN t2.id IS NULL THEN 0 ELSE 1 END) sub(c)
    ), cte2 AS (
      SELECT *, ROW_NUMBER() OVER(PARTITION BY grp ORDER BY id DESC) rn
      FROM cte
    )
    SELECT id, info
    FROM cte2
    WHERE rn BETWEEN 2 AND 4
    ORDER BY id;
    

    db<>fiddle demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-26
      • 2022-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      相关资源
      最近更新 更多