我有一个简单的事件表:
event_id | start_time | end_time
如何查询最大同时事件数?
最佳答案
我的回答与哈利的第一个回答非常相似。不过,我会尝试进行稍微不同的性能优化……跳到最后以避免对原因的漫无边际的解释……
Harry的第一个答案(核心逻辑)
SELECT MAX(overlapAtEnd)
FROM
(
SELECT
COUNT(1) AS overlapAtEnd
FROM
your_table AS t1,
your_table AS t2
WHERE
t1.end_time BETWEEN t2.start_time AND t2.end_time
GROUP BY t1.event_id
) AS foo
处理时间最长的地方是连接。
对于表中的每条记录,您选择 (t1.end time)。然后,您再次在表中搜索 (t1.end_time >= start_time) 以及您搜索的所有匹配记录 (t1.end_time <=>=>
现在,您很容易在 start_time 上创建索引。这使得第一次检查 (t1.end_time >= start_time) 更快;
- 索引是一种用于极速搜索的搜索树
- 这使得找到第一个匹配记录非常快
- 索引本质上是有序的
- 这意味着它知道“第一场比赛之后的所有比赛也比赛”
虽然最后一部分很关键,因为它意味着......即使在使用索引进行第一次检查(t1.end_time >= start_time)之后,我们仍然可以留下很多记录来进行第二次检查(t1.end_time <=>=>
[在索引中包含 end_time 在这里没有帮助,很快就会讨论]
0, '10:00', '10:04' COUNT(*) WHERE '10:04' >= start_time == 4
1, '10:01', '10:06' COUNT(*) WHERE '10:06' >= start_time == 4
2, '10:02', '10:09' COUNT(*) WHERE '10:09' >= start_time == 5
3, '10:04', '10:07' COUNT(*) WHERE '10:07' >= start_time == 4
4, '10:08', '10:12' COUNT(*) WHERE '10:12' >= start_time == 6
5, '10:12', '10:17' COUNT(*) WHERE '10:17' >= start_time == 7
6, '10:15', '10:18' COUNT(*) WHERE '10:18' >= start_time == 8
7, '10:18', '10:22' COUNT(*) WHERE '10:22' >= start_time == 10
8, '10:19', '10:24' COUNT(*) WHERE '10:24' >= start_time == 10
9, '10:22', '10:25' COUNT(*) WHERE '10:25' >= start_time == 10
=> leaves 68 rows to check the second condition; (t1.end_time <= t1.end_time)
假设事件分布相对平稳,每条记录将(大致和平均)与表的一半匹配。这意味着您正在执行 (n*n/2) 检查,其中 n 是表中的记录数。即使有 100 条记录,这也会产生 5000 张支票。在 2000 条记录下,您将进行大约 200 万次检查!
自然倾向于将 end_time 字段添加到索引中。但是,这无济于事。 (start_time, end_time) 的索引创建一个向下到每个唯一的 start_time 的搜索树,然后在每个唯一的 start_time 下有一个单独的 end_times 搜索树。
在我上面的示例中,每个 start_time 都是唯一的。这意味着您仍然需要执行所有 68 个 end_time 检查。只有 start_time 检查从索引中受益。
我们需要做的是尝试使用单一的“start_time”索引来做比现在更多的事情。我们需要为查询引擎提供更多信息。
一个例子是使用“最大事件持续时间”。例如,我们可能会发现没有任何事件持续超过 8 分钟。这将为我们提供以下查询...
SELECT MAX(overlapAtEnd)
FROM
(
SELECT
COUNT(1) AS overlapAtEnd
FROM
your_table AS t1,
your_table AS t2
WHERE
t1.end_time >= t2.start_time
AND t1.end_time <= t2.end_time
AND t1.end_time <= t2.start_time + [max_event_duration]
GROUP BY t1.event_id
) AS foo
在我上面给出的示例中应用 8 分钟持续时间的示例,我们将 68 次 end_time 检查减少到 34 次。
0, '10:00', '10:04' COUNT(*) WHERE '10:04' BETWEEN start_time AND start_time + 8 == 4
1, '10:01', '10:06' COUNT(*) WHERE '10:06' BETWEEN start_time AND start_time + 8 == 4
2, '10:02', '10:09' COUNT(*) WHERE '10:09' BETWEEN start_time AND start_time + 8 == 4
3, '10:04', '10:07' COUNT(*) WHERE '10:07' BETWEEN start_time AND start_time + 8 == 4
4, '10:08', '10:12' COUNT(*) WHERE '10:12' BETWEEN start_time AND start_time + 8 == 3
5, '10:12', '10:17' COUNT(*) WHERE '10:17' BETWEEN start_time AND start_time + 8 == 2
6, '10:15', '10:18' COUNT(*) WHERE '10:18' BETWEEN start_time AND start_time + 8 == 3
7, '10:18', '10:22' COUNT(*) WHERE '10:22' BETWEEN start_time AND start_time + 8 == 4
8, '10:19', '10:24' COUNT(*) WHERE '10:24' BETWEEN start_time AND start_time + 8 == 3
9, '10:22', '10:25' COUNT(*) WHERE '10:25' BETWEEN start_time AND start_time + 8 == 3
=> leaves 34 rows to check the second condition; (t1.end_time <= t1.end_time)
=> thats half the original 68, and on bigger tables the benefit increases...
即使我们不知道事件不会超过 8 分钟,我们也可以通过检查 10 条记录来找到它。 MAX(end_time - start_time) 超过 10 条记录仍然比 check (t1.end_time <= t1.end_time)="" 超过="" 34="">=>
并且随着表的大小增加, yield 也会增加。事实上,在 [max_event_duration] 明显小于表格涵盖的整个时间跨度的情况下,您可以将 (nn/2) 平方律更改为更类似于 (nx + n) 的东西是线性的。
民主党。
SELECT
MAX(overlapAtEnd)
FROM
(
SELECT
COUNT(1) AS overlapAtEnd
FROM
your_table AS t1,
your_table AS t2
WHERE
t2.start_time <= t1.end_time
AND t2.start_time >= t1.end_time - (SELECT MAX(end_time - start_time) FROM your_table)
AND t2.end_time >= t1.end_time
GROUP BY t1.event_id
) AS foo
关于sql - 查询同时事件的最大数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/452499/
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night
这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什
我在Rails上使用带有ruby的solr。一切正常,我只需要知道是否有任何现有代码来清理用户输入,比如以?开头的查询。或* 最佳答案 我不知道执行此操作的任何代码,但理论上可以通过查看parsingcodeinLucene来完成并搜索thrownewParseException(只有16个匹配!)。在实践中,我认为您最好只捕获代码中的任何solr异常并显示“无效查询”消息或类似信息。编辑:这里有几个“sanitizer”:http://pivotallabs.com/users/zach/blog/articles/937-s