SQL - 选择除一行外相同的行

时间:2012-11-13 23:14:53

标签: sql

我非常喜欢SQL n00b而且我似乎无法解决这个问题,所以希望得到一些帮助(非常简单!)。

我有一个数据表,是从网站上删除的数据生成的。数据只是经常变化,新信息到达,旧信息消失,数据刮取每分钟都会运行。

列:TimeStamp, User, RowA, RowB, RowC

第一列是timestamp值,如果在那一分钟内没有在网页上生成新内容,则其余行通常是相同的。

我想要做的是弄清楚新数据何时到达页面与消失之间的时间。

为了做到这一点,我想我可以做一个select语句来检查除了时间戳值之外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:00到10:03之间进行的,并且可以计算它在那里3分钟。

非常感谢任何帮助。

更新
为了进一步说明这一点,这不是一个知道值的查询 - 它需要查看从查询中收到的值并比较它们以查看它们是否相同(时间戳除外) - 谢谢回复的人我非常感激

3 个答案:

答案 0 :(得分:0)

根据sql的不同,您可能希望使用日期函数来减去时间戳。如果你摆脱了clasue的位置,你会看到分组。

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

答案 1 :(得分:0)

您可以计算最大和最小时间的差异:

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

答案 2 :(得分:0)

据推测,您的数据值可以重复。在你的例子中,詹姆斯,苹果,橘子,梨可以在上午11点重新出现,这将是一个新的序列。

查询背后的想法是找到每个组结束的时间。这期待下一个记录,其中数据值不同并且时间戳更大。实际上,最小的时间戳标识该组。你实际上可以做类似向后看的事情,但我更喜欢向前看。

在标准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,user,RowA,RowB,RowC),它会有所帮助。