2016-05-17 115 views
1

我是SQL新手,在编写以下查询时遇到困难。从两个表中选择位置

方案

用户有两个地址,家庭住址(App\User),上市地址(App\Listing)。当访问者搜索郊区或邮政编码或州的列表时,如果用户的列表地址不匹配 - 但是如果家庭地址匹配 - 他们也将位于搜索结果中。

例如:如果访问者搜索Melbourne,我想要包含Melbourne的列表以及Melbourne中的地址的用户列表。

预期输出:

user_id first_name email     suburb postcode state 
1  Mathew  [email protected] Melbourne 3000  VIC 
2  Zammy  [email protected]   Melbourne 3000  VIC 

用户:

id first_name email 
1 Mathew  [email protected] 
2 Zammy  [email protected] 
3 Tammy  [email protected] 
4 Foo   [email protected] 
5 Bar   [email protected] 

列表:

id user_id hourly_rate description 
1 1  30   ABC 
2 2  40   CBD 
3 3  50   XYZ 
4 4  49   EFG 
5 5  10   Efd 

地址:

id addressable_id addressable_type post_code suburb  state latitude longitude 
3584 1   App\\User   2155  Rouse Hill NSW -33.6918372 150.9007221 
3585 2   App\\User   3000  Melbourne VIC -33.6918372 150.9007221 
3586 3   App\\User   2000  Sydney  NSW -33.883123 151.245969 
3587 4   App\\User   2008  Chippendale NSW -33.8876392 151.2011224 
3588 5   App\\User   2205  Wolli Creek NSW -33.935259 151.156301 
3591 1   App\\Listing  3000  Melbourne VIC -37.773923 145.12385 
3592 2   App\\Listing  2030  Vaucluse NSW -33.858935 151.2784079 
3597 3   App\\Listing  4000  Brisbane QLD -27.4709331 153.0235024 
3599 4   App\\Listing  2000  Sydney  NSW -33.91741 151.231307 
3608 5   App\\Listing  2155  Rouse Hill NSW -33.863464 151.271504 
+1

您可以使用连接或联合。看看是否有帮助:http://www.techrepublic.com/article/sql-basics-query-multiple-tables/ – mtrueblood

+0

你也可以发布你想要的输出,它会更容易理解 –

回答

3

试试这个。你可以检查它here

SELECT l.* 
FROM listings l 
LEFT JOIN addresses a_l ON a_l.addressable_id = l.id 
    AND a_l.addressable_type = "App\\Listing" 
    AND a_l.suburb = "Melbourne" 
LEFT JOIN addresses a_u ON a_u.addressable_id = l.user_id 
    AND a_u.addressable_type = "App\\User" 
    AND a_u.suburb = "Melbourne" 
WHERE a_l.id IS NOT NULL OR a_u.id IS NOT NULL 
+0

我如何选择'纬度和经度'作为查询返回列表? –

+0

没关系,我已经想通了http://sqlfiddle.com/#!9/54a0376/8 –

0

试试这个,

SELECT 
      a.addressable_id AS `userid`, 
      b.first_name  AS `username` 
    FROM 
      addresses AS a JOIN users AS b ON a.addressable_id=b.id 
    WHERE 
      a.suburb = 'Melbourne'; 


    if <addressable_id> has relation with <id> in listing table, 



    SELECT 
      a.addressable_id AS `userid`, 
      b.first_name  AS `username` 
    FROM 
      addresses AS a JOIN users AS b ON a.addressable_id=b.id AND addressable_type='App\\User' 
    WHERE 
      a.suburb = 'Melbourne' 
    UNION 
    SELECT 
      b.user_id AS `userid`, 
      c.first_name  AS `username` 
    FROM 
      addresses AS a JOIN listings AS b ON a.addressable_id=b.id AND addressable_type='App\\Listing' 
          JOIN users AS c ON b.user_id=c.id 
    WHERE 
      a.suburb = 'Melbourne'; 
1

按我你的问题的理解,对于任何郊区 - 访问者提供的,您要包括所有房源,其中无论是用户的地址是与郊区提供的相同或上市地址与提供的郊区相同。

假设addressable_id列在addressable_type列有关用户表和列表表的编号,基于价值,你可以用下面的查询加入并得到期望的结果:

Select l.* 
From Listings l 
    inner join Addresses a on ((a.addressable_id = l.user_Id and a.addressable_type = 'App\\User') or (a.addressable_id = l.Id and a.addressable_type = 'App\\Listings')) 
    inner join Addresses a1 On a1.addressable_id = a.addressable_id and a1.Suburb = 'Melbourne' 
+0

谢谢。我将很快检查查询。 –

+0

如果你的表很大并且有适当的索引,我想你应该在可能的情况下使用内连接来获得更好的性能。无论如何,你有你的答案,所以不用担心..你可以检查以下链接的内部连接和左连接的进一步信息.. [内连接与左连接](http://stackoverflow.com/questions/2726657/inner -join-vs-left-join-performance-in-sql-server) – Nagahornbill