【问题标题】:MySQL: Joining a table where multiple rows are part of the conditionMySQL:加入一个表,其中多行是条件的一部分
【发布时间】:2018-12-17 14:20:25
【问题描述】:

尝试从有多个相关行的连接表中选择一些行。
这是原始查询的一个非常简化的版本,因此请不要对通用表结构提出建议。

表 A

id, title
------------
1, housea
2, houseb
3, housec
4, housed

表 B

id, cid, attrib, val
--------------------
1, 1, bathrooms, 2
2, 1, bedrooms, 1
3, 2, bathrooms, 0
4, 1, pools, 1
5, 2, bedrooms, 1
6, 2, pools, 1
7, 3, bathrooms, 1
8, 4, bathrooms, 1
9, 4, bedrooms, 1

选择所有至少有一间浴室和一间卧室的对象。

所以结果只有这两个应该出现:

2, housea
4, housed

这不起作用:

SELECT a.id, title
FROM tablea a
LEFT JOIN tableb b ON b.cid = a.id
WHERE (b.attrib = "bathrooms" AND b.val > 0) AND (b.attrib = "bedrooms" AND b.val > 0)

这也不是:

SELECT a.id, title
FROM tablea a
LEFT JOIN tableb b1 ON b1.cid = a.id AND (b1.attrib = "bathrooms" AND b1.val > 0) 
LEFT JOIN tableb b2 ON b2.cid = a.id AND (b2.attrib = "bedrooms" AND b2.val > 0) 

感谢您的建议!

【问题讨论】:

  • 嗨。了解 LEFT JOIN 返回的内容:INNER JOIN 行加上由 NULL 扩展的不匹配的左表行。作为 LEFT JOIN 的一部分,始终知道您想要什么 INNER JOIN。在 LEFT JOIN ON 删除任何由 NULL 扩展的行之后,需要右表列不为 NULL 的 WHERE 或 INNER ON,即只留下 INNER JOIN 行,即“将 LEFT JOIN 转换为 INNER JOIN”。你有那个。

标签: mysql sql join


【解决方案1】:

你的第二个版本基本上是正确的,除了你想要内连接:

SELECT a.id, a.title
FROM tablea a JOIN
     tableb b1
     ON b1.cid = a.id AND (b1.attrib = 'bathrooms' AND b1.val > 0) JOIN
     tableb b2
     ON b2.cid = a.id AND (b2.attrib = 'bedrooms' AND b2.val > 0) ;

您的所有过滤都在ON 子句中,因此实际上没有任何行被过滤掉。如果您查看来自 b1b2 的列,您会看到过滤。

【讨论】:

  • 不理解您对过滤的评论。你能详细说明一下吗?
【解决方案2】:

尝试运行相关子查询,如下所示:

select a.id, a.title from tablea a where 2 >= 
(select count(b.cid) from tableb b where b.cid = a.id and b.attrib in ('bathrooms' , 'bedrooms') and b.val > 0 group by b.cid)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 2022-12-09
    相关资源
    最近更新 更多