2012-11-13 42 views
0

我非常喜歡SQL n00b,我似乎無法弄清楚這一點,所以希望得到一些幫助(它非常簡單!)。SQL - 選擇除一行外相同的行

我有一個數據表從數據被刮掉了一個網站。數據只是隨着新信息的到來而變化,舊信息消失,數據每分鐘運行一次。

列:如果是在網頁上那一分鐘不產生新的內容TimeStamp, User, RowA, RowB, RowC

的第一列是一個timestamp值和行的其餘部分通常則是相同的。

我想要做的是找出新數據到達時在頁面上,當它消失的時間。

爲此,我圖我能做到這一點檢查其中A B C是除了所述時間戳值的所有相同的行,然後比較所述第一結果和最後的結果之間的時間差的選擇語句。

例子:

10:00AM, James, Apples, Oranges, Pears 
10:01AM, James, Apples, Oranges, Pears 
10:02AM, James, Apples, Oranges, Pears 
10:03AM, James, Apples, Watermelon 

我想知道的是,該行James, Apples, Oranges, Pears在那裏,從上午10點和上午10點03分,並能計算出它在那裏3分鐘之間。

任何幫助一如既往,非常感謝。

UPDATE
爲了進一步澄清這一點,這會不會是其中的值是已知的查詢 - 這將需要看從查詢接收的值並加以比較,看看他們是相同的(除時間戳) - 感謝答覆傢伙容積我真的很感激

+2

您有名爲RowA,RowB,RowC的列嗎? – MatBailie

+0

非常奇怪,是的 - 可能需要更新,由於含糊不清 – Lance

回答

0

根據各種SQL的,你可能會想使用一款最新功能減去時間戳。如果你擺脫了哪裏,你會看到分組。

Select 
    RowA, -- Calling columns "Row" isn't confusing at all 
    RowB, 
    RowC, 
    Min(timestamp), 
    Max(timestamp), 
    Max(timestamp) - Min(timestamp) 
From 
    Scrape 
Where 
    RowA = 'James' And 
    RowB = 'Apples' And 
    RowC = 'Oranges' 
Group By 
    RowA, 
    RowB, 
    RowC 
+0

嗨勞倫斯,生病檢查了一下,當我可以測試這個和投票,如果適用! – Lance

+0

這確實假設一旦數據發生變化,它就不會在以後返回相同的值。 – MatBailie

+0

當然,如果情況並非如此,戈登的方法就是要走的路。 – Laurence

0

您可以計算從最大值和最小值的時間差:

select `user`, rowa, rowb, rowc, 
     min(`timestamp`), max(`timestamp`), 
     timediff(min(`timestamp`), max(`timestamp`)) 
from mytable 
group by `user`, rowa, rowb, rowc; 
+0

這確實假設一旦數據發生變化,它將永遠不會在以後返回相同的值。 – MatBailie

0

據推測,您的數據值可以重複。在你的例子中,詹姆斯,蘋果,橘子,梨可以在上午11:00重新出現,這將是一個新的序列。

查詢背後的想法是找出每個組何時結束。這期待着數據值不同且時間戳較大的下一個記錄。事實上,最小的這種時間戳標識了該組。你實際上可以做類似的事情,但我更喜歡向前看。

標準SQL來做到這一點的方法是使用相關子查詢(或不等值連接),具體如下:

select user, RowA, RowB, RowC, min(TimeStamp) as StartTimeStamp, 
     EndTimeStamp 
from (select User, RowA, RowB, RowC, TimeStamp, 
      (select Min(timeStamp) 
       from t t2 
       where t2.TimeStamp > t1.TimeStamp and 
        (t2.user <> t.user or 
        t2.RowA <> t.rowA or 
        t2.RowB <> t.RowB or 
        t2.RowC <> t.RowC 
        ) 
      ) as EndTimeStampe 
     from t 
    ) t 
group by user, RowA, RowB, RowC, EndTimeStamp 

注意,這個假設值是不爲NULL,因爲NULL值將自動失效甚至當「相等」時也進行比較。您可以通過兩種方式解決這個問題:

(coalesce(t2.user, '<null>') <> coalesce(t.user, '<null'>) or . . . 

(t2.user <> t.user and ((t2.user is not null and t.user is null) or (t2.user is null and t.user is not null)) 

一些SQL方言(如SQL Server 2012和Oracle)提供了更廣泛的窗函數,也可以幫助解決這個問題。

此外,如果您有非常大的表,這是相當低效率。如果你有一個索引(TimeStamp,用戶,RowA,RowB,RowC),它會有所幫助。

+0

這看起來多了一些我需要的東西,但我認爲在哪裏claus的價值將是平等的,而不是notequal - 當我今晚有機會時,我會檢查這一點,並投票什麼最適合;)謝謝堆。 – Lance

+0

錯誤,不,不等於是正確的。它正在尋找第一行在這個值不同之後 - 這給出了組的結束時間。 (如果這是最後一個組,則爲NULL) – MatBailie

+0

@Dems。 。 。子查詢爲每個組找到EndTimeStamp。結束時間戳是每個組的標識符(以及其他列)。和外面的查詢組合在一起,將相應的行結合在一起。 –