【问题标题】:Alternative to SQL Sub Query for Returning Prior Matching Records用于返回先前匹配记录的 SQL 子查询的替代方法
【发布时间】:2016-07-03 20:07:56
【问题描述】:

SQL Azure 数据库 V12 (SQL Server 2016)

给定以下基本表结构:

MyTable
==============
Id int PK
TheDate datetime2 not null
TheValue varchar(50) not null
-- other fields

还有下面的SQL:

select 
    (   select count(*) 
        from MyTable mt2 
        where 
            mt2.TheValue = mt1.TheValue
            and mt2.TheDate < mt1.TheDate
    ) as PriorCount
    , mt1.TheDate, mt1.TheValue 
from MyTable mt1
where mt1.TheDate between '2016-01-01' and '2017-01-01'
order by mt1.TheDate desc

示例输出:

PriorCount   TheDate                 TheValue
===============================================
   1         2016-06-01 00:00:00     Foo
   2         2016-05-01 00:00:00     Bar
   1         2016-04-01 00:00:00     Bar
   0         2016-03-01 00:00:00     Foo
   0         2016-02-01 00:00:00     Bar

我已经查看了OVER Clause,但找不到任何东西来返回之前的计数。是否有替代 SQL 查询来返回 PriorCount 而无需子选择?

【问题讨论】:

  • 您也可以只使用OUTER APPLYCROSS APPLY 使用该给定值计算给定日期之前的所有内容,这在技术上不是子选择。
  • @ZLK,你能举个例子吗?也许是另一种答案?
  • 你可以把你的子查询写成一个应用,比如SELECT Z.PriorCount, mt1.TheDate, mt2.TheValue FROM MyTable mt1 CROSS APPLY (SELECT COUNT(*) FROM MyTable WHERE TheValue = mt1.TheValue AND TheDate &lt; mt1.TheDate) Z(PriorCount) WHERE...
  • @ZLK - 交叉应用也可以;也许考虑将其添加为替代答案。

标签: sql sql-server azure-sql-database sql-server-2016


【解决方案1】:

您可以将COUNTORDER BY 子句一起使用:

select count(*) over (partition by TheValue order by TheDate) - 1 as PriorCount,
       mt1.TheDate, mt1.TheValue 
from MyTable mt1
where mt1.TheDate between '2016-01-01' and '2017-01-01'
order by mt1.TheDate desc

编辑:

如果要将COUNT 应用于整个表,则可以使用以下查询:

select PriorCount, TheDate, TheValue
from (
   select count(*) over (partition by TheValue 
                         order by TheDate) - 1 as PriorCount,
          TheDate, TheValue 
   from MyTable 
   order by TheDate desc) as t
where t.TheDate between '2016-01-01' and '2017-01-01'

【讨论】:

  • 这几乎可以工作。但是,PriorCount 应该包括所有日期,而不仅仅是 where 子句中的日期范围。我认为over子句只包括当前的结果集?
  • @MetroSmurf OVER 子句应用于查询返回的记录之后 WHERE 执行。您可以在子查询中使用OVER,并在外部查询中应用WHERE。请检查我所做的修改。
  • 编辑确实可以稍微调整一下,回复:order by TheDate desc) as t 需要删除订单,否则会出现 SQL 错误:The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified. 我还注意到新查询明显慢了,但我'会玩索引,看看我能想出什么。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-07
  • 2011-07-18
  • 2022-10-17
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
相关资源
最近更新 更多