使用分组依据和按日期排序的 SQL 选择

标签 sql sql-server sql-server-2008

我正在使用 SQL Server 2008,我想知道是否可以在一个 select 语句中完成我的查询并且无需子查询。

如果记录中的字段在最近 10 个创建的记录中为 true,我想将变量设置为 true,如果该字段在最后 10 个记录中为 true,则变量将为 true,而如果为 false,则变量将为 true false,如果记录总数小于 10 则该变量也将为 false。

我的问题是,要获取最新 10 个创建的记录,我需要按降序进行用户排序并对前 10 条进行过滤,因此我的查询应如下所示,其中它不是有效查询:

declare @MyVar bit
set @MyVar = 0

select top(10) @MyVar = 1 from MyTable
where SomeId = 1000 and SomeFlag = 1
group by SomeId
having count(SomeId) >= 10
order by CreatedDate

请向我提供您的建议。

这是一个例子,假设我们有下表,并说我想检查每个 id 的最新 3 条记录:

ID  Joined  CreatedDate
1   true    03/27/2013
1   false   03/26/2013
1   false   03/25/2013
1   true    03/24/2013
1   true    03/23/2013

2   true    03/22/2013
2   true    03/21/2013
2   true    03/20/2013
2   false   03/19/2013

3   true    03/18/2013
3   true    03/17/2013

对于 id="1",结果将为 FALSE,因为最近创建的 3 条记录的 JOINED 字段值不为 true。

对于 id="2",结果将为 TRUE,因为最近创建的 3 条记录在这 3 条记录中具有真正的 JOINED 字段。

对于 id="3",结果将为 FALSE,因为要检查的最新创建的记录必须至少为 3 条记录。

最佳答案

(OP指定2008年之前给出的答案。以下仅适用于2012年)

<小时/>

此查询给出(对于每个 ID 值)最后 10 行中标志等于 1 的行数。将其过滤为仅计数为 10 的行应该足够简单(如果需要),并将其限制为单个 ID 值。

如果没有更好的示例数据,我暂时就这样:

;with Vals as (
    select
        *,
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY CreatedDate DESC) as rn,
        SUM(CASE WHEN Flag = 1 THEN 1 ELSE 0 END)
                 OVER (PARTITION BY ID
                       ORDER BY CreatedDate ASC
                       ROWS BETWEEN 9 PRECEDING AND CURRENT ROW) as Cnt
    from
        T1
)
select * from Vals where rn = 1

(这确实取决于 OVER clause 的 SQL Server 2012 版本 - 但您没有指定哪个版本)

结果:

ID          Flag  CreatedDate             rn                   Cnt
----------- ----- ----------------------- -------------------- -----------
1           1     2012-01-12 00:00:00.000 1                    10
2           1     2012-01-12 00:00:00.000 1                    9
3           1     2012-01-12 00:00:00.000 1                    6

(只有 ID 1 符合您的条件)

示例数据:

create table T1 (ID int not null,Flag bit not null,CreatedDate datetime not null)
insert into T1 (ID,Flag,CreatedDate) values
(1,1,'20120101'),
(1,0,'20120102'),
(1,1,'20120103'),
(1,1,'20120104'),
(1,1,'20120105'),
(1,1,'20120106'),
(1,1,'20120107'),
(1,1,'20120108'),
(1,1,'20120109'),
(1,1,'20120110'),
(1,1,'20120111'),
(1,1,'20120112'),

(2,1,'20120101'),
(2,1,'20120102'),
(2,1,'20120103'),
(2,1,'20120104'),
(2,1,'20120105'),
(2,1,'20120106'),
(2,0,'20120107'),
(2,1,'20120108'),
(2,1,'20120109'),
(2,1,'20120110'),
(2,1,'20120111'),
(2,1,'20120112'),

(3,1,'20120107'),
(3,1,'20120108'),
(3,1,'20120109'),
(3,1,'20120110'),
(3,1,'20120111'),
(3,1,'20120112')

关于使用分组依据和按日期排序的 SQL 选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15758508/

相关文章:

mysql - 如何在 SQL 子查询中使用 NOT IN?

sql-server - 通过在T-SQL中设置种子从均匀分布生成随机值

SQL Server 2005 使用查找表更新查询

java - JDBC 中大型 IN 子句的替代方案,如何使用 Java 中的表值参数?

mysql - 生成更新查询

sql - Postgres : function accepting a hashmap or similar type as argument

java - JDBC 异常 : Operation not allowed after ResultSet closed

sql - SQL Server自增主键的上限

c# - 使用 SQL Server 管理对象将存储过程从一个 SQL Server 2008 复制到另一个 SQL Server 2008

sql - 确定导致 SQL 中约束冲突的值/列?