是否应该使用UNION完成此T-SQL

时间:2013-05-21 08:31:14

标签: sql-server tsql join union

使用下表(称之为TableA),我需要创建一个SQL语句,选择两组数据并将它们组合在一起。首先,我需要选择那些Status = 1和DateCreated比指定日期更大(意味着更新)的行,我将其称为StartDate。我还需要选择Status = 0和DateCreated也大于指定日期BUT的所有行,其中结果按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

最好是使用加入两个结果的联盟还是有更好的效率?

3 个答案:

答案 0 :(得分: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
    )

不可否认,您只需要Status 0的行号,但在所有行中运行它不会有任何损害。

答案 1 :(得分: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;

An SQLfiddle to test with

答案 2 :(得分: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