我有四张表格如下:
tenant
+----+------------+
| id | name |
+----+------------+
| 1 | John Smith |
| 2 | Anna Jones |
+----+------------+
property
+----+-------------+---------------+
| id | landlord_id | address |
+----+-------------+---------------+
| 1 | 1 | King Street 1 |
| 2 | 1 | Green Grove 2 |
| 3 | 2 | Queen Stree 3 |
+----+-------------+---------------+
tenant_has_property
+-----------+-------------+
| tenant_id | property_id |
+-----------+-------------+
| 1 | 1 |
| 1 | 2 |
+-----------+-------------+
landlord
+----+-----------------+
| id | name |
+----+-----------------+
| 1 | Best Homes Ltd. |
| 2 | RealEstates Inc |
+----+-----------------+
现在我想获得一个从房东id = 1
房租房产的租户名单当我运行如下查询时:
SELECT
tenant.id, tenant.name
FROM
tenant, property, tenant_has_property
WHERE
tenant.id = tenant_has_property.tenant_id AND
tenant_has_property.property_id = property.id AND
property.landlord_id = 1
我收到重复的行:
+----+------------+
| id | name |
+----+------------+
| 1 | John Smith |
| 1 | John Smith |
+----+------------+
我知道将查询更改为
SELECT
DISTINCT tenant.id, tenant.name ...
会删除重复的行,但我的问题是:
是否可以避免使用DISTINCT并以不返回重复行的方式构造JOIN?已经尝试了INNER,LEFT JOINS的所有组合,没有太多运气:(
非常感谢任何建议
答案 0 :(得分:1)
真正的版本是
SELECT id, name FROM tenant
WHERE id IN
(SELECT tenant_has_property.tenant_id FROM
tenant_has_property
WHERE tenant_has_property.property_id IN
(SELECT property.id FROM property WHERE property.landlord_id = 1 )
)
我认为这对你有用。但我没有尝试它,因为我没有访问我的终端上的SQL服务器。
答案 1 :(得分:1)
Jonh Smith是Best Homes Ltd的两个房产的租户,所以他出了两次,所以你不得不搞砸一下或者说不同等。
为了得到你想要的东西,你需要另一张桌子说
组合 哪个会给你一个连接帐篷到kandlord的记录。 然后你可以用它来将投资组合链接到财产。即您将多个租约分组,因此您不必使用tennat_has_property表来查看关系。
是否值得重构架构我不知道。
答案 2 :(得分:0)
您可以使用IN
子句使用以下查询执行此操作:
SELECT
t.id, t.name
FROM
tenant t
WHERE
t.id IN (
SELECT
thp.tenant_id
FROM
tenant_has_property thp
INNER JOIN property p ON thp.property_id = p.id
WHERE
p.landlord_id = 1
)
但我强烈建议您不要使用此方法,因为内部SQL语句往往比JOIN查询运行得慢。您可以使用GROUP BY
按tenant.id对结果进行分组。
SELECT
t.id, t.name
FROM
tenant t
INNER JOIN tenant_has_property thp ON t.id=thp.tenant_id
INNER JOIN property p ON thp.property_id = p.id
WHERE
p.landlord_id = 1
GROUP BY t.id
据我所知,仅使用JOIN语句实现此目的是不可能的。因为MySQL将按照您的请求加入记录,然后最终会有以下行:
t.id, t.name , thp.tenant_id, thp.property_id, p.id, p.landlord_id, p.address 1 , John Smith, 1 , 1 , 1 , 1 , King Street 1 1 , John Smith, 1 , 2 , 2 , 1 , Green Grove 2
由于您只请求t.id和t.name字段,因此MySQL仅向您返回列,但它不知道它们具有重复值。您必须通过向select子句添加DISTINCT
或告诉MySQL如何对记录进行分组并返回单行来强制它。