2015-02-04 31 views
1

我正在使用t-sql。T-SQL中的行內時間比較

我有一個簡單的表稱爲mytable

它看起來像這樣:

ID Num Date 
1  0  2015-01-01 00:00:00 
1  0  2015-01-02 00:00:00 
1  1  2015-01-03 00:00:00 
1  2  2015-01-04 00:00:00 
2  0  2015-01-01 00:00:00 
2  1  2015-02-01 00:00:00 
2  0  2015-03-01 00:00:00 
3  1  2014-01-01 00:00:00 
3  2  2014-01-02 00:00:00 
4  2  2015-02-01 00:00:00 
4  0  2015-02-02 00:00:00 
4  2  2015-02-05 00:00:00 

與此表的情況很簡單,任何時候的12值已輸入到表中,後來的值(按時間順序)不能是0。這是數據輸入錯誤,必須通過將0更改爲2來解決。

因此,在上面的簡化示例中,ID對於人員24有錯誤。

對於人2,有人在0鍵安裝在2015-01-01 00:00:00,而對於人4,有人在2015-01-01 00:00:000鍵。

我是SQL的新手,並且誠實地寧願將整個事情導出爲csv,在R中打開它,找到問題,然後使用數據庫中的更新語句更新值。但我覺得這是一個讓SQL變得更好的機會 - 不幸的是,我被卡住了。

這裏我需要一些方法來比較表中的行,因爲它們是按ID分組,還要考慮這種按時間順序的情況。我試過笛卡兒加入CASE聲明,但沒有奏效。 任何幫助將不勝感激。

+1

的SQL Server版本您使用的? –

+0

7.0。是的,我正在研究一個非常舊的系統。 –

+0

您只需要0個條目或比以前的記錄少的東西? – Hogan

回答

2

此查詢將選擇所有問題記錄:

SELECT * 
FROM mytable AS t 
WHERE Num = 0 AND EXISTS (SELECT 1 
          FROM mytable 
          WHERE Num IN (1,2) AND ID = t.ID AND Date < t.Date) 

它選擇所有Num=0記錄其中有一張Num=1一個Num=2記錄有同一ID

輸出:

ID Num Date 
------------------ 
2 0 2015-03-01 
4 0 2015-02-02 

要更新表簡單地做:

UPDATE mytable 
SET Num = 2 
FROM mytable AS t 
WHERE Num = 0 AND EXISTS (SELECT 1 
          FROM mytable 
          WHERE Num IN (1,2) AND ID = t.ID AND Date < t.Date) 
+0

的條目,你能解釋一下'SELECT 1'的含義嗎?數字'1'的用途是什麼? –

+0

@ MattO'Brien「SELECT 1」表示對於符合「WHERE」子句條件的「mytable」的每條記錄,僅選擇一個「1」。這就是'EXISTS'工作所需要的全部! –

0

您可以加入一個表回到自身,把邏輯的,就像這樣:

select * 
from mytable t 
join mytable p on t.id = p.id 
        and t.date > p.date 
        and t.num < p.num 

這會給你「額外」的行,如果有多個先前的問題米要通過解決這個問題,你可以組:

select id, Date, max(priornum) as max_prior 
from (
    select t.id, t.Date, p.num as priornum 
    from mytable t 
    join mytable p on t.id = p.id 
       and t.date > p.date 
       and t.num < p.num 
) sub 
group by id, Date 

或反覆使用不同的(對於更現代的服務器版本):

select distinct t.id, t.num, t.Date, 
       max(p.num) OVER (partition by t.id, t.Date) as max_prior 
from mytable t 
join mytable p on t.id = p.id 
       and t.date > p.date 
       and t.num < p.num