【问题标题】:MySQL selecting rows when a linked field matchesMySQL在链接字段匹配时选择行
【发布时间】:2016-04-26 00:13:41
【问题描述】:

我正在尝试构建一个查询,在其中获取内容与搜索匹配的所有变体。 例如,根据下表,我想获取包含 content = "red"

的所有变体
 -------------------------------------------
| ID | Product | Variant | Option | Content |
 -------------------------------------------
|  1 | Shirt   | 1       | size   | S       |   
|  2 | Shirt   | 1       | color  | red     |
|  3 | Shirt   | 2       | size   | M       |   
|  4 | Shirt   | 2       | color  | red     |
|  5 | Shirt   | 3       | size   | L       |   
|  6 | Shirt   | 3       | color  | red     |
|  7 | Shirt   | 4       | size   | M       |
|  8 | Shirt   | 4       | color  | blue    |
 -------------------------------------------

我希望结果类似于:

 -------------------------------------------
| ID | Product | Variant | Option | Content |
 -------------------------------------------
|  1 | Shirt   | 1       | size   | S       |   
|  2 | Shirt   | 1       | color  | red     |
|  3 | Shirt   | 2       | size   | M       |   
|  4 | Shirt   | 2       | color  | red     |
|  5 | Shirt   | 3       | size   | L       |   
|  6 | Shirt   | 3       | color  | red     |
 -------------------------------------------

当内容 = M 时,结果会是这样的

 -------------------------------------------
| ID | Product | Variant | Option | Content |
 -------------------------------------------
|  3 | Shirt   | 2       | size   | M       |   
|  4 | Shirt   | 2       | color  | red     |
|  7 | Shirt   | 4       | size   | M       |
|  8 | Shirt   | 4       | color  | blue    |
 -------------------------------------------

我希望这是有道理的。 谢谢!

我做了一个小提琴 http://sqlfiddle.com/#!9/63e64e/2

【问题讨论】:

  • sqlfiddle.com +1 带来了很好的问题

标签: mysql select field


【解决方案1】:

使用自联接

SELECT v1.*
FROM variant AS v1
JOIN variant AS v2 ON v1.variant = v2.variant
WHERE v2.content = 'red'

这在功能上等同于 Tin Tran 的查询,但不需要编写子查询,因此更简单一些。您需要检查 EXPLAIN 输出以确保它们的处理方式相同。

【讨论】:

  • 谢谢你,工作就像魅力一样,我可以在这里构建第二个过滤器:sqlfiddle.com/#!9/be3bbe/6 使用以下查询 SELECT v1.* FROM variant AS v1 JOIN variant AS v2 ON v1.variant = v2.variant WHERE v2.content = 'S' JOIN variant AS v3 ON v1.variant = v3.variant WHERE v3.content = 'winter'
  • 首先出现所有JOIN 子句,然后是单个WHERE 子句和条件之间的AND
  • 你可能想做SELECT v1.* FROM variant AS v1 JOIN variant AS v2 ON v1.variant = v2.variant WHERE v2.content = 'S' OR v2.content = 'winter'
  • 实际上,“OR”标签不起作用,它带来了所有...我发布了查询的磨损版本,这个是正确的:SELECT v1.* FROM variant AS v1 JOIN variant AS v2 ON v1.variant = v2.variant AND v2.content = 'S' 加入变体 AS v3 ON v1.variant = v3.variant AND v3.content = 'winter'
  • @Rafanake 一般来说,单个表的条件应该在WHERE 子句中,ON 子句应该只用于与正在连接的表相关的条件。例外情况是外部联接,您也可以在 ON 子句中将条件放在子表上。但是,将额外的条件放在 ON 中是等效的。
【解决方案2】:
SELECT v.id,v.product,v.variant,v.option,v.content
FROM variant v
INNER JOIN (SELECT variant FROM variant WHERE content = 'red')v2
ON v.variant = v2.variant
ORDER BY ID ASC

如果您想获得其他结果,只需将 'red' 更改为 'M'

http://sqlfiddle.com/#!9/63e64e/7

我注意到在你的 sqlfiddle 中它有一个 M 和 Yellow 的变体,如果你将 'red' 字符串设置为 'M' 会显示在结果中

【讨论】:

  • 非常感谢,这对我帮助很大!
【解决方案3】:
SELECT * 
FROM variant
WHERE
variant.variant 
IN
(
  SELECT variant.variant 
  FROM variant 
  WHERE variant.content = 'red'
)

这应该比较容易理解。您有一个内部查询,它首先使用可用选项搜索每个变体。然后你有外部查询搜索从变体搜索返回的所有变体的所有值。一种更优雅的写法可能是这样的,

SELECT *
FROM variant
INNER JOIN 
(
  SELECT variant2.variant 
  FROM variant variant2 
  WHERE variant2.content = 'red'
) variant2
ON variant.variant = variant2.variant

在此示例中,您必须至少命名一个返回的表以区分它们。这是因为您正在调用同一个表的两个实例。

SELECT *
FROM variant
JOIN variant AS variant2 ON variant.variant = variant2.variant
WHERE variant2.content = 'red'

这是另一个输出相同结果的示例。与此不同的是您在单个查询中运行它。

可以在此处找到了解联接的良好来源:https://technet.microsoft.com/en-us/library/ms191472(v=sql.105).aspx

我最喜欢的连接图表之一可以在这里找到:http://www.codeproject.com/KB/database/Visual_SQL_Joins/Visual_SQL_JOINS_orig.jpg 它缺少一些技巧,但它确实提供了一个很好的基本概念,让您了解连接可以做什么。

【讨论】:

  • 谢谢,请检查这些链接!
  • MySQL 在优化WHERE col IN (SELECT ...) 查询方面是出了名的糟糕,所以尽量避免它们。
猜你喜欢
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2013-04-30
  • 2011-10-04
  • 2021-06-14
  • 2012-01-16
相关资源
最近更新 更多