2013-04-11 69 views
0

混亂,但是,這裏的情況:選擇項的第一次出現在最後的分組

我們已經有了對應於一個地方坐鎮程序以1個分鐘的間隔序列號。

Sequence# | Timestamp 
    1  | 2012-04-11 12:00:00 
    2  | 2012-04-11 12:01:00 
    2  | 2012-04-11 12:02:00 
    2  | 2012-04-11 12:03:00 
    3  | 2012-04-11 12:04:00 
    5  | 2012-04-11 12:05:00 
    5  | 2012-04-11 12:06:00 
    6  | 2012-04-11 12:07:00 
    1  | 2012-04-11 12:08:00 
    2  | 2012-04-11 12:09:00 
    2  | 2012-04-11 12:10:00 
    2  | 2012-04-11 12:11:00 
    3  | 2012-04-11 12:12:00 

的序列的持續時間可以改變,但間隔始終是相同的(每1分鐘精確)。

正如你所看到的,序列重複。 我如何才能找到Seqence n的最新開始發帖

所以,如果我想搜索序列2,我希望回到2 | 2012-04-11 12:09:00因爲它是序列的最新,啓動次數2

+0

數據在哪裏?在數據庫中?或者正在從流中讀取? – 2013-04-11 16:26:01

+0

@PhilipKearns:鑑於問題標有[mysql] ... – 2013-04-11 16:27:02

+0

是的,上下文在這裏很重要。你想要做什麼? – doliver 2013-04-11 16:32:03

回答

4

嘗試:

SELECT t1.* FROM `table_name` t1 
LEFT JOIN `table_name` t2 
on t1.`Sequence` = t2.`Sequence` and 
    t1.`Timestamp` = t2.`Timestamp` + interval 1 minute 
WHERE t1.`Sequence`=2 and t2.`Sequence` is null 
ORDER BY t1.`Timestamp` DESC LIMIT 1 

SQLFiddle here

+0

我不認爲我遵循這是如何工作的。按照時間順序,這不會返回序列2的第一次出現嗎?你的第二個'ON'需求永遠不會是真的,所以左連接總是有t2.Sequence爲空,所以Sequence 2的每一個出現都滿足這個查詢,它會返回最新的。我的查詢比這個更復雜,所以嘗試這種方法並不容易,所以我需要知道這裏真正發生了什麼。 – StuckAtWork 2013-04-11 16:45:12

+0

+1,它工作。但如果你能解釋它是如何工作的?我的實際數據庫(愚蠢)將時間戳存儲爲「年」,「月」,「日」......字段,而不是選擇,所以我需要知道在這裏發生了什麼邏輯,以便將它複製到這些字段中。 – StuckAtWork 2013-04-11 16:48:45

+0

@StuckAtWork:除了有史以來的第一條記錄外,第二個「on」條件將始終爲真 - 它將當前時間戳與前一個記錄相連,即一分鐘前。結合第一個'on'條件將當前記錄鏈接到最後一條記錄,**如果它們是相同的序列 - 這使得在外部連接表上使用「is null」條件的左連接實際上是相同的做一個'not exists'(外部連接/ null組合應該在MySQL中執行得更好)。 – 2013-04-11 16:55:20

0

我想這是你想要的...

SELECT * FROM `table_name` WHERE `Sequence`=2 ORDER BY `Timestamp` DESC LIMIT 1 
+0

這個查詢會輸出'2 | 2012-04-11 12:11:00'而不是'2 | 2012-04-11 12:09:00'如你所說,但我認爲'2 | 2012-04-11 12:11:00'實際上是你要找的 – 2013-04-11 16:31:21

+0

我不認爲它是 - 「最新的**開始**發生」(我強調)。 – 2013-04-11 16:32:29

+0

不是;尋找'12:09:00'。我們給了兩個參數,'startSeq'和'endSeq'。我需要從startSeq開始到endSeq結束的那些行的信息,所以如果startSeq是2,我需要序列2的更早的(但仍然是最新的分組)。 – StuckAtWork 2013-04-11 16:33:11

0

這是你想要的嗎?

$desired_sequence=2; 

$query="SELECT * FROM `table_name` ORDER BY `Timestamp` DESC"; 
$result = mysql_query($query); 
if (mysql_errno()) { die("ERROR ".mysql_errno($link) . ": " . mysql_error($link)); } 

$found_desired=0; 
while($row = mysql_fetch_array($result)) 
{ 
    if($row['Sequence']==$desired_sequence) 
    { 
     $found_desired=1; 
     $timestamp=$row['Timestamp']; 
    } 

    if(($found_desired==1) && ($row['Sequence']!=$desired_sequence)) 
    { 
     return; // End the while loop because $timestamp will have your desired output. 
    } 
} 
+0

我敢肯定,這種方法是可行的,但它並不像我想的那樣優雅或快速。該數據庫存儲了大約1mil的記錄以及幾千個唯一的序列號,所以我擔心這會在不斷詢問一些獨特的行時對性能產生嚴重影響。 – StuckAtWork 2013-04-11 16:51:13

+0

讓我知道如果你找到更好的方法...我有興趣知道。 – 2013-04-11 16:54:26

+0

我想如果你可以給初始查詢添加一個WHERE,並且只有在給定的時間之後查詢結果,那麼你肯定是在之後開始的序列。這將大大減少返回的記錄。也許甚至有一段時間。您提供的信息越多,效率就越高。 – 2013-04-11 16:56:08

0

我不確定你到底在這裏。我寫了一些代碼,如果數據在文本文件中,這些代碼就可以工作。如果數據在數據庫中,則會更容易。不過,我從你的例子中假設你有| |分離它不在數據庫中的數據。

function findLastOccurenceOfSequence ($sequenceNumber) 
{ 
    if (@!is_int ($sequenceNumber)) 
     throw new Exception ("Expected param1 to be an integer"); 
    $data = file_get_contents ("testFile.txt"); 
    $dataArray = explode ("\n", $data); 
    $dataArray = array_reverse ($dataArray); 
    $returnLine = ""; 
    $sequenceStarted = false; 
    foreach ($dataArray as $key => &$dataLine) 
    { 
     $pieces = explode ("|", $dataLine); 
     if (count ($pieces) != 2) 
      continue; 
     list ($thisSequenceNum, $timeStamp) = $pieces; 
     $thisSequenceNum = intval (trim ($thisSequenceNum)); 
     if ($thisSequenceNum == $sequenceNumber) 
     { 
      $sequenceStarted = true; 
      $returnLine = $dataLine; 
     } 
     else if ($sequenceStarted) 
     { 
      break; 
     } 
    } 

    if ($key == count ($dataArray)) 
    { 
     throw new Exception ("Sequence not found!"); 
    } 

    return $returnLine; 
} 

echo "OCCURRENCE: " . findLastOccurenceOfSequence (2); 
相關問題