【问题标题】:Select first appearance of item in last grouping在最后一个分组中选择第一次出现的项目
【发布时间】:2013-04-11 16:16:09
【问题描述】:

令人困惑,但是,情况如下:

我们有序列号,对应于程序每隔 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 的最新开始出现。

【问题讨论】:

  • 数据在哪里?在数据库中?还是从流中读取?
  • @PhilipKearns:鉴于该问题被标记为 [mysql]...
  • 是的,上下文在这里很重要。你到底想做什么?
  • 这些行显然在我的真实数据库表中包含更多信息。我需要通过 SQL 查询返回问题中指示的行,但我不确定如何获取最近 groupstart (按序列号分组时) )。

标签: php mysql sorting pdo sequence


【解决方案1】:

试试:

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.

【讨论】:

  • 我不认为我遵循它的工作原理。这不是按时间顺序返回序列2的第一次出现吗?你的第二个ON 要求永远不会是真的,所以左连接总是有 t2.Sequence 为空,所以序列 2 的每次出现都满足这个查询并且它会返回最新的。我的查询比这更复杂,所以尝试这种方法并不容易,因此我需要知道这里真正发生了什么方法..
  • +1,它有效。但如果你能解释一下它是如何工作的..?我的实际数据库(愚蠢地)将时间戳存储为yearmonthday... 字段,而不是选择,所以我需要知道这里发生了什么逻辑以便用这些字段复制它.
  • @StuckAtWork:第二个on 条件将始终为真,除了第一个记录 - 它将当前时间戳链接到前一个时间戳,一分钟前。将此与第一个 on 条件相结合,将当前记录链接到最后一条记录,if 它们是相同的序列 - 将其与外部联接表上的 is null 条件进行左联接是有效的与执行not exists 相同(外部联接/null 组合应该在 MySQL 中表现更好)。
  • @StuckAtWork:所以,你有一组记录(在 t1 上),其中没有相同序列的前一个记录 - 或者换句话说,一个系列的每个开始出现具有相同序列的记录。 WHERE t1.`Sequence`=2 条件将其限制为序列 2; ordering by t1.Timestamp DESCENDING 以相反的时间顺序返回它们(最新的在前),而 LIMIT 1 确保只返回第一条记录(即最新的)。
  • 哦,我现在明白了。那是……嗯,这真的很聪明,实际上。它基本上告诉 SQL 查找,直到找到一个序列 2 之前没有另一个 2。绝对是答案,尽管我必须弄清楚如何转换那些愚蠢的单个字段以使用它。谢谢!
【解决方案2】:

我想这就是你想要的......

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

【讨论】:

  • 此查询将输出 2 | 2012-04-11 12:11:00 而不是 2 | 2012-04-11 12:09:00 如您所说,但我认为 2 | 2012-04-11 12:11:00 实际上是您要查找的内容
  • 我不认为它是-“最新的,开始的事件”(我的重点)。
  • 不;寻找12:09:00。我们得到了两个参数,startSeqendSeq。我需要从startSeq 开头到endSeq 结尾的这些行的信息,所以如果startSeq2,我需要序列2 的较早(但仍然是最近的分组)。
  • 我冒昧地假设它在 mysql 数据库中,因为这个问题被标记为 mysql
  • 好的...我现在明白你想要做什么,但你让我难住了。我认为您必须遍历每条记录并将序列号与前一条记录进行比较,看看它是否相同。给我一点时间把一些代码放在一起。
【解决方案3】:

这是你想要的吗?

$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.
    }
}

【讨论】:

  • 我敢肯定,这种方法会起作用,但它不像我想要的那样优雅或快速。该数据库存储了大约 100 万条记录,其中包含数千个唯一序列号,因此我担心在不断请求一些唯一行时这可能会对性能产生严重影响。
  • 如果您找到更好的方法,请告诉我...我很想知道。
  • 我想如果您可以将WHERE 添加到初始查询中,并且仅在您确定序列开始后的给定时间后查询结果。这将大大减少返回的记录。甚至可能给定一个时间段。您提供的信息越多,效率就越高。
【解决方案4】:

我不确定你到底想要什么。如果数据在文本文件中,我编写了一些代码。如果数据在数据库中,那就更容易了。但是,我假设因为在您的示例中您有一个 |分离不在数据库中的数据。

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2021-05-10
    • 2012-12-07
    • 1970-01-01
    • 2012-07-23
    • 2016-05-10
    相关资源
    最近更新 更多