我有三个表,比如:
*table1*
id | val1 | val2 | val3 | val4 | val5
1 | ... | ... | ... | ... | ...
2 | ... | ... | ... | ... | ...
3 | ... | ... | ... | ... | ...
... etc
和
*table2*
id | som1 | som2
1 | ... | ...
2 | ... | ...
3 | ... | ...
... etc
和
*table3*
id | col1 | col2
1 | ... | ...
2 | ... | ...
3 | ... | ...
... etc
第三个表中的 col2 将始终包含来自 val3、val4 或 val5 来自第一个表。第二个表只是为了完整性而包含在问题中,而不是问题。
我的查询如下:
$db = new PDO(...);
$stmt = $db->prepare("SELECT t2.som1 AS t2som1,
t1.val1 AS t1v1,
t1.val2 AS t1v2,
t1.val3 AS t1v3,
t1.val4 AS t1v4,
t1.val5 AS t1v5,
t3.col1 AS t3col1
FROM table1 t1
JOIN table2 t2 ON t1.val2 = t2.som2
JOIN table3 t3 ON t1.val3 = t3.col2
WHERE (t1.val4=:input OR t1.val5=:input)
AND (t1.val1=1 OR t1.val1=2)");
$stmt->execute(array('input'=>$inputVal));
$result = $stmt->fetchAll();
这是一种享受,完全符合预期。
但是!
我不只是需要 t3col1 来获得 t1.val3 = t3.col2。 t1.val4 = t3.col2 和 t1.val5 = t3.col2
我可以构建这条线:
JOIN table3 t3 ON (t1.val3 = t3.col2 OR t1.val4 = t3.col2 OR t1.val5 = t3.col2)
但是我不知道哪个值被用来获取t3col1。而且它只返回一个值,而不是所有三个值。
看到我的问题了吗!?
我想拥有
SELECT t2.som1 AS t2som1,
...
t3.col1 AS t3col1, // for condition t1.val3 = t3.col2
t3.col1 AS t3col2, // for condition t1.val4 = t3.col2
t3.col1 AS t3col3 // for condition t1.val5 = t3.col2
这可以做到吗?
澄清
IF val1、val2 和 val3 都包含值,我希望返回一个单个行,其中表 3 中的所有三场比赛。不是三个单独的行,它们除了匹配列外都是相同的。
This SQLFiddle是我不想要的例子。请注意,除了 t3col1 列外,所有内容都是相同的。这应该是一行,包含所有 t3col1 值。
/澄清
我估计我可以分别加入表 3 次:
SELECT t2.som1 AS t2som1,
...
t3.col1 AS t3col1
t4.col1 AS t3col2
t5.col1 AS t3col3
FROM table1 t1
JOIN table2 t2 ON t1.val2 = t2.som2
JOIN table3 t3 ON t1.val3 = t3.col2 // for condition t1.val3 = t3.col2
JOIN table3 t4 ON t1.val4 = t3.col2 // for condition t1.val4 = t3.col2
JOIN table3 t5 ON t1.val5 = t3.col2 // for condition t1.val5 = t3.col2
WHERE (...)
AND (...)
但我这样做是否会降低性能(即 4 个 JOINS),这与我尝试做的方式相反,仅使用 2 个?
奖金!
有时 val3、val4 和/或 val5 将为空(但col2 从不为空)。对于那些具有空值的情况,是否所有 table3 JOIN 都需要是 LEFT JOIN?
编辑 1
根据您的要求,我已经在 SQLFiddle 中进行了设置,但该服务时断时续。
你可以找到它here
编辑 2
我多次尝试连接 table3:
SELECT t2.som1 AS t2som1,
...
t3.col1 AS t3col1
t4.col1 AS t3col2
t5.col1 AS t3col3
FROM table1 t1
JOIN table2 t2 ON t1.val2 = t2.som2
JOIN table3 t3 ON t1.val3 = t3.col2 // for condition t1.val3 = t3.col2
JOIN table3 t4 ON t1.val4 = t3.col2 // for condition t1.val4 = t3.col2
JOIN table3 t5 ON t1.val5 = t3.col2 // for condition t1.val5 = t3.col2
WHERE (...)
AND (...)
并最终为每场比赛获得一行。我应该有 7 个结果,结果得到了 90 多个。
val1 总会有一个值,val2 和 val3 是否填充每次都不同。但是当这三个都有值时,我不希望它有三个单独的返回。相反,我只想要一个包含所有三个匹配项的返回值。
编辑 4(澄清是 3...)
由于 Siraj 的回答,来自 EDIT 2 的 multiple JOINs 最终起作用了。问题是我使用了:
JOIN table3 t3 ON t1.val3 = t3.col2
JOIN table3 t4 ON t1.val4 = t3.col2
JOIN table3 t5 ON t1.val5 = t3.col2
我应该在什么时候使用:
JOIN table3 t3 ON t1.val3 = t3.col2
JOIN table3 t4 ON t1.val4 = t4.col2
JOIN table3 t5 ON t1.val5 = t5.col2
注意到区别了吗?它只是每个等号后的 t3.col2 - 他们需要引用正确的表格!其余的都保持不变,鲍勃是你的阿姨!
最佳答案
下面的查询会给你你想要的数据:
SELECT t2.som1 AS t2som1,
t1.val1 AS t1v1,
t1.val2 AS t1v2,
t1.val3 AS t1v3,
t1.val4 AS t1v4,
t1.val5 AS t1v5,
t3.col1 AS t3col1,
t3.col2 AS t3col2,
CASE WHEN t1.val3 = t3.col2 THEN t3.col1 ELSE '' END AS 't3col11',
CASE WHEN t1.val4 = t3.col2 THEN t3.col1 ELSE '' END AS 't3col21',
CASE WHEN t1.val5 = t3.col2 THEN t3.col1 ELSE '' END AS 't3col31',
CASE WHEN t1.val3 = t3.col2 THEN 't1col3'
ELSE CASE WHEN t1.val4 = t3.col2 THEN 't1col4' ELSE 't1col5'
END END AS ColumnName
FROM table1 t1
JOIN table2 t2 ON t1.val2 = t2.som2
JOIN table3 t3 ON (t1.val3 = t3.col2 OR t1.val4 = t3.col2 OR t1.val5 = t3.col2)
GROUP BY t2som1,t1v1, t1v2, t1v3, t1v4, t1v5
最后一列“ColumnName”告诉您哪个 t1 列与该值匹配。
编辑 - 使用左连接
SELECT t2.som1 AS t2som1,
t1.val1 AS t1v1,
t1.val2 AS t1v2,
t1.val3 AS t1v3,
t1.val4 AS t1v4,
t1.val5 AS t1v5,
t3.col1 AS t3col1,
t3.col1 AS t3col1,
t4.col1 AS t3col2,
t5.col1 AS t3col3
FROM table1 AS t1
LEFT JOIN table2 t2 ON t1.val2 = t2.som2
LEFT JOIN table3 t3 ON t1.val3 = t3.col2
LEFT JOIN table3 t4 ON t1.val4 = t4.col2
LEFT JOIN table3 t5 ON t1.val5 = t5.col2
关于PHP、MySQL - 获取从单个 JOIN 返回的多个可识别行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37012721/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我正在尝试修改当前依赖于定义为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之间的所有版本,你可以这
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c