0

使用下表(称为 TableA),我需要创建一个 SQL 语句来选择两组数据并将它们组合在一起。首先,我需要选择那些Status = 1DateCreated 大于(意味着更新)指定日期的行,我将其称为 StartDate。我还需要选择所有那些Status = 0DateCreated 也大于指定日期但结果按 DateCreated 降序排序的行,并且这些记录的数量限制为 2。

因此,如果我的表数据如下所示:

ID   Status        DateCreated
1      1         2013-05-01 14:00
2      1         2013-05-01 15:00
3      1         2013-05-01 16:00
4      0         2013-05-01 17:00
5      0         2013-05-01 18:00
6      0         2013-05-01 19:00
7      0         2013-05-01 20:00

我设置了@startDate to 2013-05-01 14:30,我希望结果集如下所示:

2      1         2013-05-01 15:00
3      1         2013-05-01 16:00
6      0         2013-05-01 19:00
7      0         2013-05-01 20:00

最好使用连接两个结果的联合来完成此操作,还是有更好更有效的方法?

4

3 回答 3

0

试试这个——

询问:

DECLARE @temp TABLE 
(
      ID INT
    , [Status] INT
    , DateCreated DATETIME
)
INSERT INTO @temp(ID, [Status], DateCreated) 
VALUES
    (1, 1, '20130501 14:00:00'),
    (2, 1, '20130501 15:00:00'),
    (3, 1, '20130501 16:00:00'),
    (4, 0, '20130501 17:00:00'),
    (5, 0, '20130501 18:00:00'),
    (6, 0, '20130501 19:00:00'),
    (7, 0, '20130501 20:00:00')

DECLARE @startDate DATETIME = '20130501 14:30:00'

SELECT 
      ID
    , [Status]
    , DateCreated 
FROM (
    SELECT 
          ID
        , [Status]
        , DateCreated
        , ROW_NUMBER() OVER (PARTITION BY [Status] ORDER BY DateCreated DESC) AS rn
    FROM @temp
) t
WHERE DateCreated > @startDate 
    AND (
          [Status] % 1 = 1 
        OR
          rn < 3
    )
ORDER BY t.DateCreated

输出:

ID          Status      DateCreated
----------- ----------- -----------------------
2           1           2013-05-01 15:00:00.000
3           1           2013-05-01 16:00:00.000
6           0           2013-05-01 19:00:00.000
7           0           2013-05-01 20:00:00.000
于 2013-05-21T09:08:39.033 回答
0

无需UNION- 只需WHERE对您的要求进行条款翻译:

declare @t table (ID int not null,Status int not null,DateCreated datetime not null)
insert into @t(ID,Status,DateCreated) values
(1,1,'2013-05-01T14:00:00'),
(2,1,'2013-05-01T15:00:00'),
(3,1,'2013-05-01T16:00:00'),
(4,0,'2013-05-01T17:00:00'),
(5,0,'2013-05-01T18:00:00'),
(6,0,'2013-05-01T19:00:00'),
(7,0,'2013-05-01T20:00:00')

declare @startDate datetime
set @startDate ='2013-05-01T14:30:00'

;With Numbered as (
    select *,ROW_NUMBER() OVER (PARTITION BY Status ORDER BY DateCreated desc) as rn
    from @t
)
select * from Numbered
where
    DateCreated > @startDate and
    (
        Status = 1 or
        Status = 0 and rn <= 2
    )

诚然,您只需要Status0 的行号,但在所有行上运行它应该没有任何危害。

于 2013-05-21T08:57:52.887 回答
0

你应该用你的真实数据集来衡量性能差异,但只是为了给你一个替代方案,你可以用它来编写它ROW_NUMBER()

SELECT id, status, datecreated FROM (
  SELECT id, status, datecreated,
      ROW_NUMBER() OVER (PARTITION BY status ORDER BY DateCreated DESC) rn
  FROM Table1 WHERE DateCreated > '2013-05-01 14:30'
) a
WHERE status = 1 OR rn < 3
ORDER BY DateCreated;

一个用于测试的 SQLfiddle

于 2013-05-21T08:58:29.010 回答