假设我有这张表:
item_id tag_id
------- ------
1 1
1 2
2 2
2 3
正如您可能想象的那样,这是一个表格,我在其中引用了一些项目和属于它们的标签。一个项目可以有多个标签,并且可以为多个项目选择一个标签。
假设我还有一个特定的标签集合(例如 tag_id = 50、73 和 119)和一个带有 ID(由 item_id 引用)的“项目”表。
是否有一个高效查询可以给我:
我尝试过的
SELECT COUNT(*) FROM
(
SELECT COUNT(*) AS c FROM items_tags it JOIN items i ON i.id = it.item_id
WHERE (tag_id=7 OR tag_id=95 OR tag_id=150) AND `status`='active'
GROUP BY item_id
) t1 WHERE c=3 <-- c= number of tags
我可以得到两个结果,但查询效率非常低(看起来)。在用 EXPLAIN 检查后,我想摆脱 OR 给出的“范围”。
细化我的问题:问题是我得到了一个编写非常糟糕的 PHP 框架,它通过各种标签 ID 迭代了 900 多次。假设您有一个或多个固定 ID(选定的标签),它会遍历所有 900 多个标签,以查找具有给定标签以及迭代标签的项目的出现次数(这是一种优化搜索,只显示所有给定标签加一个的元素)。
给定的代码是这样工作的:我选择一个或多个标签并将它们的 ID 放入查询字符串中。假设我选择了标签 54 和 77。 该代码必须找到同时具有标签 54 和 77 的项目的每个项目 ID,并将它们一一列出:我们获得“具有选定标签的项目”列表。
然后,它提供了优化搜索的选择,奇怪的部分来了:PHP 代码循环遍历所有 900 多个标签,并且对于每次迭代,它都需要一个标签,并计算有多少项目具有所有标签54、77 和迭代中的那个。 如果计数 > 0,它会显示带有计数的标签的名称,过滤掉所有其项目与所选标签没有任何链接的标签。
以一种“强度”较低的方式实现相同的结果会很好。
最佳答案
要获取匹配所有标签的项目 ID 列表,您可以使用此查询:
SELECT items.id
FROM items
JOIN items_tags ON items.id = items_tags.item_id
WHERE (items_tags.tag_id IN (7,95,150))
AND (items.status = 'active')
GROUP BY items.id
HAVING COUNT(DISTINCT items_tags.tag_id) = 3
请注意,如果您确定同一项目永远不会有重复标签,则可以将 COUNT(DISTINCT items_tags.tag_id) 替换为 COUNT(*)效率。
要计算这些项目的数量,请将其包装在 COUNT 查询中:
SELECT COUNT(*)
FROM (
SELECT items.id
...
) t
要获取项目列表,请将其包装在这个 SELECT 查询中:
SELECT *
FROM items
WHERE id IN (
SELECT items.id ...
)
更新
要在与原始列表组合时获取每个剩余标签的项目计数,您可以这样做:
SELECT tag_id, COUNT(DISTINCT item_id)
FROM items_tags
WHERE item_id IN (
SELECT items.id
...
)
AND tag_id NOT IN (7,95,150)
GROUP BY tag_id
关于php - 在 mysql 表中查找标记项的出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15484334/
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm
我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr
我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin
我想找到给定字符串中的所有匹配项,包括重叠匹配项。我怎样才能实现它?#Example"a-b-c-d".???(/\w-\w/)#=>["a-b","b-c","c-d"]expected#Solutionwithoutoverlappedresults"a-b-c-d".scan(/\w-\w/)#=>["a-b","c-d"],but"b-c"ismissing 最佳答案 在积极的前瞻中使用捕获:"a-b-c-d".scan(/(?=(\w-\w))/).flatten#=>["a-b","b-c","c-d"]参见Rubyde
在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g