【问题标题】:Inner join in Select Statement to create a variable in SQL ServerSelect 语句中的内连接以在 SQL Server 中创建变量
【发布时间】:2017-10-31 18:50:31
【问题描述】:

我有一个claimstable,如下所示。

Time             Terminal_ID  Claims   Count
-------------------------------------------
2017-10-19 06:03:00     1      451        1
2017-10-19 06:04:00     1      452        2
2017-10-19 06:05:00     1      452.3      2
2017-10-19 06:06:00     1      458        2
2017-10-19 06:03:00     9      459        6 
2017-10-19 06:04:00     9      461.2      5
2017-10-19 06:05:00     9      462        2
2017-10-19 06:06:00     9      463        1

我选择timeclaim 并从我的表中创建一个新列Claims_Change。在此之后,我将它插入到一个临时表中。

我的预期输出是:

          Time       Terminal_ID  Claims   Count Claims_change
    ---------------------------------------------------------
    2017-10-19 06:03:00     1      451        1     Null
    2017-10-19 06:04:00     1      452        2     1
    2017-10-19 06:05:00     1      452.3      2     0.3
    2017-10-19 06:06:00     1      458        2     5.7
    2017-10-19 06:03:00     9      459        6     Null
    2017-10-19 06:04:00     9      461.2      5     2.2
    2017-10-19 06:05:00     9      462        2     0.8
    2017-10-19 06:06:00     9      463        1     1

这是我的查询:

select
    [Time], Terminal_ID, Claims, 
    convert(decimal(12, 3), y.[Claims] - (select t1.[Claims] 
                                          from claimstable t1 
                                          where t1.Terminal_ID = y.Terminal_ID 
                                            and t1.[Time] = (select max([Time])
                                                             from claimstable t2
                                                             where  t2.Terminal_ID = t1.Terminal_ID 
                                                               and t2.[Time] < y.[Time])
                    )) as Claims_change
into 
    #temptable
from 
    claimstable as y

当我测试 5000 行时,它工作正常,但是,当我测试 100,000 行时,我收到这样的错误,

消息 512,第 16 级,状态 1,第 42 行
子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

我正在阅读一些较旧的posts,推荐的答案是使用inner join

另外,就我而言,我不知道如何准确地编写以使用inner join 获取Claims_change 变量。

任何帮助都会很棒。

【问题讨论】:

  • 你也能显示预期的输出吗?
  • 您正试图从一个数字中减去一个结果集。如果该结果集恰好返回多个值,则 SQL Server 不知道您实际希望它做什么。例如,什么是 3 - (1, 4, 6)?如果您打算返回多行,那么您需要在您的问题中添加其他信息,指定您的确切要求。如果不是,那么您需要弄清楚为什么要获得多行以及将其缩小到一行的业务规则。
  • @TomH,您是对的,在您发表评论后,我对数据进行了一些挖掘,发现不知何故有重复记录。我找到并修复了它,感谢您的精彩评论 :)

标签: sql sql-server select inner-join


【解决方案1】:

如果您使用的 SQL Server 版本支持LAG,请使用

select t.*,t.claims-lag(t.claims) over(partition by terminal_id order by time) as claims_change
from claimstable t

LAG 根据指定的排序和分区从上一行获取指定列的值。第一行(在分区中)的LAG 将是NULL。您可以使用可选参数来指定默认值。

【讨论】:

  • 我不知道 LAG。我正在使用 Sql Server 2016,我会确保,我会阅读它!
【解决方案2】:

你可以试试这个。

select
    [Time], Terminal_ID, y.Claims, convert(decimal(12,3), y.[Claims]- t2.[Claims] ) as Claims_change
into 
    #temptable
from 
    claimstable as y
    OUTER APPLY ( SELECT TOP 1 t1.[Claims] FROM claimstable t1 where
            t1.Terminal_ID = y.Terminal_ID AND y.[Time] > t1.[Time] ORDER BY [Time] DESC ) as  t2

结果:

Time                    Terminal_ID Claims       Claims_change
----------------------- ----------- ------------ ---------------
2017-10-19 06:03:00.000 1           451.00       NULL
2017-10-19 06:04:00.000 1           452.00       1.000
2017-10-19 06:05:00.000 1           452.30       0.300
2017-10-19 06:06:00.000 1           458.00       5.700
2017-10-19 06:03:00.000 9           459.00       NULL
2017-10-19 06:04:00.000 9           461.20       2.200
2017-10-19 06:05:00.000 9           462.00       0.800
2017-10-19 06:06:00.000 9           463.00       1.000

【讨论】:

  • 感谢您的努力,我会试试这个,而且我是 `OUTER APPLY` 的新手。我会尝试更多地阅读它!然而,正如 Tom H 在上面的 cmets 中提到的那样,我认为他是对的。我有一条重复记录导致查询失败。
猜你喜欢
  • 2014-10-05
  • 2014-10-28
  • 2021-01-28
  • 2013-05-24
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
  • 2016-06-21
相关资源
最近更新 更多