2014-03-26 1 views
0

에 가입 나는 다음과 같은 3 개 테이블이 있습니다를 사용하여 값을 위해 왼쪽

users 
| id | name | address | 
|----+-------+----------+ 
| 1 | user1 | address1 | 
| 2 | user2 | address2 | 

locations 
| id | user_id | name  | 
|----+---------+-----------+ 
| 1 | 1  | location1 | 
| 2 | 1  | location2 | 
| 3 | 2  | location3 | 

orders 
| id | user_id | from_id | to_id | 
|----+---------+---------+-------+ 
| 1 | 1  | 1  | 2  | 
| 2 | 1  | 1  | 0  | 

from_id 또는 to_id 사용자의 주소가이 경우에 사용 된 의미, 0을 가질 수 있습니다. 는 '순진'를 실행

이 테이블에 조인

SELECT u.name uname, fl.location flocation, tl.location tlocation 
FROM users u, orders o, locations fl, locations tl 
WHERE u.id = o.user_id 
    AND o.from_id = fl.id 
    AND o.to_id = tl.id 

0 레코드를 표시하지 않습니다

: 내가보고 싶은 것이

user1 | location1 | location2 

다음 데이터입니다

user1 | location1 | location2 
user1 | location1 | address1 

mysql을 사용하면 이러한 결과를 보여주기 위해 조인을 확장 할 수 있습니까?

SELECT u.name uname, IF(fl.id, fl.location, u.address) AS flocation, IF(tl.id, tl.location, u.address) AS tlocation 
FROM users u 
    INNER JOIN orders o ON u.id = o.user_id 
    LEFT JOIN locations fl ON o.from_id = fl.id 
    LEFT JOIN locations tl ON o.to_id = tl.id; 

을 내가 제안을 할 수 있다면, 난 당신이 테이블을 조인하는 방법으로 WHERE 절을 사용하지 않는 것이 좋습니다 것입니다 :

답변

0

다음 SQL은 수행해야합니다.

+0

가 큰 응답을 위해 너희들을 감사 반환 할 열 값을 결정하기 위해 SELECT리스트에 조건식을 사용! – Tamir

0
SELECT u.name uname, fl.location flocation, tl.location tlocation 
FROM users u 
left join orders o 
      on u.id = o.user_id 
left join locations fl 
      on o.from_id = fl.id 
left join locations tl 
      on o.to_id = tl.id 

이렇게하면 모든 사용자에 대한 데이터가 제공됩니다.

그리고 Tim Burch 제안 된대로 ANSI SQL 구문을 사용하는 것이 가장 좋습니다.

0

from 및 to 이름 모두에 대해 사용자의 주소를 기본값으로 사용하려면 왼쪽 결합을 수행하고 COALESCE을 사용하여 null을 주소로 바꿉니다.

SELECT 
    u.name uname, 
    COALESCE(fl.name, u.address) flocation, 
    COALESCE(tl.name, u.address) tlocation 
FROM users u 
JOIN orders o ON u.id = o.user_id 
LEFT JOIN locations fl ON o.from_id = fl.id 
LEFT JOIN locations tl ON o.to_id = tl.id 

An SQLfiddle to test with.

0

조인 작업을 위해 "쉼표"구문을 포기하는 것이 좋습니다. JOIN 키워드를 사용하고 WHERE 절 대신 조인 술어를 ON 절로 이동하십시오.

orders의 모든 행을 반환하려면 다른 테이블의 "일치하는"행이 있는지 여부에 관계없이 외부 조인 작업을 사용할 수 있습니다. 선택 목록

, 당신은 COALESCE 함수를 사용 locations에서 location 컬럼 NULL인지의 여부를 테스트하고, 그 때 user address 표에서 열을 반환 할 수있다. X가 NULL THEN ELSE Y의 X END`이면

SELECT u.name uname 
    , COALESCE(fl.location,u.address) flocation 
    , COALESCE(tl.location,u.address) tlocation 
    FROM orders o 
    LEFT 
    JOIN users u 
    ON u.id = o.user_id 
    LEFT 
    JOIN locations fl 
    ON fl.id = o.from_id 
    LEFT 
    JOIN locations tl 
    ON tl.id = o.to_id 

COALESCE(x,y) 함수는 본질적 CASE "의 약어이다.

locations 테이블의 일치하는 행을 찾을 수 있지만 location 열에 실제로 NULL이 포함되는 경우에는 어떤 경우가 있습니다.

더 정확하게 스펙과 일치하려면 orders 테이블의 to_id 열에서 "0"의 값을 테스트 할 수 있습니다 :

SELECT u.name uname 
    , IF(o.from_id = 0, u.address, fl.location) flocation 
    , IF(o.to_id = 0, u.address, tl.location) tlocation 
    FROM orders o 
    LEFT 
    JOIN users u 
    ON u.id = o.user_id 
    LEFT 
    JOIN locations fl 
    ON fl.id = o.from_id 
    LEFT 
    JOIN locations tl 
    ON tl.id = o.to_id 

을하지만 코너 경우가있다; locations에 id 값이 "0"인 행이 있으면 어떻게 될까요?

규범적인 패턴은 locations 테이블에서 행이 반환되었는지 여부를 테스트하는 것입니다. 일치하는 것이 발견되면 NOT NULL이 될 것이고, 일치하는 것이 발견되지 않으면 NULL이 될 것입니다 :

SELECT u.name uname 
    , IF(fl.id IS NULL, u.address, fl.location) flocation 
    , IF(tl.id IS NULL, u.address, tl.location) tlocation 
    FROM orders o 
    LEFT 
    JOIN users u 
    ON u.id = o.user_id 
    LEFT 
    JOIN locations fl 
    ON fl.id = o.from_id 
    LEFT 
    JOIN locations tl 
    ON tl.id = o.to_id 

"세 가지 모든 쿼리는"일반 "사례에 대해 동일한 결과를 반환합니다. 그들은 "코너 케이스"가 어떻게 처리되는지에 차이가 있습니다. 요약

:

  • 사용 운전 테이블로 ordersLEFT [OUTER] JOIN 작업.