以LEFT JOIN PostgreSQL为条件

时间:2019-11-13 23:40:23

标签: postgresql

我有3张桌子:

  • 一个拥有“位置”信息。
  • 其他包含有关用户首选的“位置”(来自位置)的信息
  • 其他包含有关用户访问过的位置的信息。

我想显示访问的地址信息,但是如果不可用,请使用用户首选位置的地址信息。

我在为左联接设置条件时遇到麻烦(如果一个条件不可用,则从另一张桌子中抢走)

这是我的查询:

SELECT rew.cust_id,
    rew.location_name,
    CASE WHEN rew.used_location IS NULL THEN customer.home_location ELSE rew.used_location END, 
    locations.street_address,
    locations.city,
    locations.zip_code FROM rew
INNER JOIN customer ON rew.cust_id = customer.cust_id
LEFT JOIN locations ON rew.used_location = locations.location_name
WHERE rew.cust_id = 12

此打印以下内容

cust_id    |   location_name   |   used_location    |   street_address   | city   |   zip_code
-----------------------------------------------------------------------------------------------
   12      |   place 1         |     place 1        |   123 My Street    | City   |     00000
   12      |   place 1         |     place 1        |   NULL             | NULL   |     NULL
   12      |   place 1         |     place 1        |   NULL             | NULL   |     NULL

在此查询中,第二条记录和第三条记录的used_location实际上是customer.home_location的条件,但它没有连接地址上的信息。如何设置为null,然后将customer.home_location中的地址放在JOIN上的位置

3 个答案:

答案 0 :(得分:2)

尝试一下:

SELECT rew.cust_id,
    rew.location_name,
    CASE WHEN rew.used_location IS NULL THEN customer.home_location ELSE rew.used_location END, 
    locations.street_address,
    locations.city,
    locations.zip_code FROM rew
INNER JOIN customer ON rew.cust_id = customer.cust_id
LEFT JOIN locations ON 
    rew.used_location = locations.location_name
    AND rew.used_location IS NOT NULL
    OR customer.home_location = locations.location_name
    AND rew.used_location IS NULL
WHERE rew.cust_id = 12

答案 1 :(得分:1)

我认为您想在customerrew之间进行LEFT JOIN(在这个方向上,对于每个客户来说,都有可能访问过该位置-或者在rew和{ {1}}),然后将其与customer表结合起来以获取有关所选位置的信息。

查询如下:

locations

或者,嵌套查询更加清晰:

SELECT customer.cust_id,
    locations.location_name,
    locations.street_address,
    locations.city,
    locations.zip_code
FROM customer
LEFT JOIN rew USING (cust_id)
INNER JOIN locations ON COALESCE(rew.used_location, customer.home_location) = locations.location_name
WHERE customer.cust_id = 12

我也将SELECT result.cust_id, locations.location_name, locations.street_address, locations.city, locations.zip_code FROM ( SELECT customer.cust_id, COALESCE(rew.used_location, customer.home_location) AS location_name FROM customer LEFT JOIN rew USING (cust_id) WHERE customer.cust_id = 12 ) AS result INNER JOIN locations USING (location_name) 表达式简化为CASE调用。

答案 2 :(得分:1)

您的地址连接始终在rew.used_location列上(根据您的定义,该列可能为NULL)。您需要使连接成为条件,类似于使第三显示列成为条件。

SELECT rew.cust_id,
       CASE WHEN rew.used_location IS NULL THEN customer.home_location ELSE rew.used_location END AS location_to_show,
       rew.location_name,
       locations.street_address,
       locations.city,
       locations.zip_code FROM rew
INNER JOIN customer ON rew.cust_id = customer.cust_id
LEFT JOIN locations ON  
  CASE 
    WHEN rew.used_location IS NULL THEN customer.home_location
    ELSE rew.used_location
    END = locations.location_name

SQL Fiddle To Try This