SQL选择问题

时间:2015-05-26 18:32:50

标签: sql sql-server

我有一个包含以下列和值的表格

Date                 Nbr   NewValue OldValue
5/20/2015 14:23:08    123   abc      xyz
5/20/2015 15:02:10    123   xyz      abc
5/21/2015 08:10:02    123   xyz      pqr
5/21/2015 10:10:05    456   lmn      ijk

从上表中我想从123中选择5/21/205,从456选择5/21/2015。我不想从nbr 123中选择5/20,因为OldValueNewValue在一天结束时没有变化。

如何为这种要求编写select语句。

4 个答案:

答案 0 :(得分:0)

SELECT * FROM YOURTABLE AS T1
INNER JOIN YOURTABLE AS T2 ON T1.NBR=T2.NBR AND T1.OLDVALUE<>T2.NEWVALUE

内部加入你自己的表

答案 1 :(得分:0)

我对这个问题的理解是你只想选择带有新数据的行

IF TABLE1.OLDVALUE <> TABLE2.OLDVALUE;
BEGIN
SELECT DISTINCT NBR
FROM [TABLENAME] AS TABLE1
INNER JOIN [TABLENAME] AS TABLE2 ON TABLE1.NBR = TABLE2.NBR
WHERE DATE = '5/21/2015' -- I recommend using sysdate here but your choice
END;

答案 2 :(得分:0)

使用where not exists子句:

从[表]中选择&#34;日期&#34;,Nbr a 哪里不存在(从[表格]中选择*,其中a.nbr = b.nbr和b.newvalue = a.oldvalue)

答案 3 :(得分:0)

如果您至少使用SQL Server 2008,则可以使用CTE确定哪个条目代表每天[Nbr]的第一个条目,哪个条目代表最后一个条目,然后比较两个条目根据其他答案中的建议,使用自联接查看实际更改的位置。例如:

-- Sample data from the question.
declare @TestData table ([Date] datetime, [Nbr] int, [NewValue] char(3), [OldValue] char(3));
insert @TestData values
    ('2015-05-20 14:23:08', 123, 'abc', 'xyz'),
    ('2015-05-20 15:02:10', 123, 'xyz', 'abc'),
    ('2015-05-21 08:10:02', 123, 'xyz', 'pqr'),
    ('2015-05-21 10:10:05', 456, 'lmn', 'ijk');

with [SequencingCTE] as
(
    select *,
        -- [OrderAsc] will be 1 if and only if a record represents the FIRST change 
        -- for a given [Nbr] on a given day.
        [OrderAsc] = row_number() over (partition by convert(date, [Date]), [Nbr] order by [Date]),

        -- [OrderDesc] will be 1 if and only if a record represents the LAST change
        -- for a given [Nbr] on a given day.
        [OrderDesc] = row_number() over (partition by convert(date, [Date]), [Nbr] order by [Date] desc)
    from
        @TestData
)

-- Match the original value for each [Nbr] on each day with the final value of the
-- same [Nbr] on the same day, and get only those records where an actual change
-- has occurred.
select
    [Last].*
from
    [SequencingCTE] [First]
    inner join [SequencingCTE] [Last] on
        convert(date, [First].[Date]) = convert(date, [Last].[Date]) and
        [First].[Nbr] = [Last].[Nbr] and
        [First].[OrderAsc] = 1 and
        [Last].[OrderDesc] = 1
where
    [First].[OldValue] != [Last].[NewValue];