我正在尝试以SQL查询的形式找到针对以下问题的优雅解决方案。
新记录将插入Log表中。 我需要检测我之前没见过的任何新记录(在最后一小时内插入)并生成警报(例如,这些记录的数量> 0)
ID, Url, DOB
1, site1.com/page1, "5/06/2012 20:01"
2, site2.com/page2, "5/06/2012 21:20"
3, site1.com/page1, "6/06/2012 10:05"
如果“now”是6/06/2012 10:40 - 我看到插入了1条新记录(id = 3),但我不想生成警报,因为我们之前已经看过这个URL(id = 1)。
如果有的话 4,site3.com / pageX,“6/06/2012 10:08” 然后我想生成一个警报(返回计数= 1),因为这行是在最后一小时插入的,我们之前没有看到它。
实施它的最佳方法是什么?理想情况下没有嵌套查询
答案 0 :(得分:5)
我认为这就是你所追求的。这将在最后一小时检索新条目(其中new表示最后一小时没有访问过相同的URL)
SELECT *
FROM Log
WHERE DOB > DATEADD(HOUR, -1, CURRENT_TIMESTAMP)
AND NOT EXISTS
( SELECT 1
FROM Log T1
WHERE T1.URL = Log.URL
AND T1.DOB < DATEADD(HOUR, -1, CURRENT_TIMESTAMP)
)
上的工作示例
修改强>
刚看到你只需要一个计数的评论:
SELECT COUNT(*)
FROM Log
WHERE DOB > DATEADD(HOUR, -1, CURRENT_TIMESTAMP)
AND NOT EXISTS
( SELECT 1
FROM Log T1
WHERE T1.URL = Log.URL
AND T1.DOB < DATEADD(HOUR, -1, CURRENT_TIMESTAMP)
)
编辑2
我不确定为什么只需要一个选择,但是,最接近一个选择的是:
SELECT COUNT(*)
FROM ( SELECT *, MIN(DOB) OVER(PARTITION BY URL) [FirstViewed]
FROM Log
) Log
WHERE FirstViewed >= DATEADD(HOUR, -1, CURRENT_TIMESTAMP)
如果在过去一小时内访问过两次同一页面,则仍会返回2。
答案 1 :(得分:2)
这个做了另类选择,首先通过分组搜索唯一网址,然后在最后一小时提取这些网址。
SELECT x1.*
FROM
(SELECT URL,
COUNT(ID) AS urlcount,
MAX(DOB) AS uniqueurl
FROM Log
GROUP BY URL HAVING count(ID) = 1
OR MIN(DOB) > dateadd(HOUR ,-1 , CURRENT_TIMESTAMP)) AS x1
WHERE x1.uniqueurl > dateadd(HOUR ,-1 , CURRENT_TIMESTAMP);
http://sqlfiddle.com/#!3/250e0/45/0
我无法弄清楚这是否具有可接受的性能而没有查看解释,但我认为该组中涉及的排序操作可能是一个瓶颈
答案 2 :(得分:1)
没有嵌套查询(SQLFiddle):
SELECT COUNT(DISTINCT T0.URL)
FROM Log AS T0
LEFT OUTER JOIN Log AS T1 ON
T1.URL = T0.URL
AND T1.DOB < DATEADD(HOUR, -1, CURRENT_TIMESTAMP)
WHERE
T0.DOB > DATEADD(HOUR, -1, CURRENT_TIMESTAMP)
AND T1.ID IS NULL
但它确实与GarethD的解决方案相同,性能明智。
答案 3 :(得分:0)
试试这个:
SELECT DISTINCT a.id, a.url, a.dob
FROM Log a JOIN Log b ON (a.url = b.url)
WHERE UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(a.DOB)<=3600
AND UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(b.DOB)>3600;
它应该返回遵循您在问题中指定的模式的所有记录。
观察我使用UNIX_TIMESTAMP
将日期转换为秒,因此减法将返回时间差,表示为秒数。并且必须在3600秒内进行比较。
编辑:
该句已得到纠正。但这是针对MySQL的(我没有看到sql-server2005标签)
答案 4 :(得分:-1)
select distinct(a.url) from tbl a, tbl b where a.dob>(now-hour) and b.dob<=(now-hour) and a.url=b.url;
(用你选择的数据库替换时间操作。索引urls和dob)
同样希望您的数据库足够明智,可以在使用索引进行连接和连接之前进行dob比较。