2010-07-22 2 views
17

두 테이블이 있습니다. 왼쪽 테이블의 각 레코드에 대해 오른쪽 테이블의 레코드 하나만 반환되는 방식으로이 레코드를 조인하고 싶습니다. 아래 예를 포함 시켰습니다. 실제 데이터는 약 4M 행이므로 서브 쿼리와 임시 테이블을 피하고 싶습니다. 또한 가장 오른쪽 테이블의 어떤 레코드가 일치하는지 상관하지 않습니다. 감사!MySQL JOIN 쿼리 도움말 : 가장 왼쪽 테이블의 모든 행에 대해 가장 오른쪽 테이블에서 한 행만 반환하십시오.

테이블 사용자 :

------------- 
| id | name | 
------------- 
| 1 | mike | 
| 2 | john | 
| 3 | bill | 
------------- 

테이블 거래 :

--------------- 
| uid | spent | 
--------------- 
| 1 | 5.00 | 
| 1 | 5.00 | 
| 2 | 5.00 | 
| 3 | 5.00 | 
| 3 | 10.00 | 
--------------- 

예상 출력 :

--------------------- 
| id | name | spent | 
--------------------- 
| 1 | mike | 5.00 | 
| 2 | john | 5.00 | 
| 3 | bill | 5.00 | 
--------------------- 
+0

모두가 user.id (기본 키) 및 user.name별로 그룹화되는 이유는 무엇입니까? 기본 키별로 그룹화 한 후에는 다른 것을 필요로하지 않습니다. 나는 무언가를 놓치고 있습니까, 아니면 우리 모두가 단지 조랑말을 복사하고 있습니까? – TheJacobTaylor

+2

@TheJacobTaylor : 표준 SQL에서는 GROUP BY에 집계로 래핑되지 않은 열을 포함해야합니다. ANSI 표준은 불필요한 하위 그룹화가 관련된 경우 모든 열을 정의하지 않는 기능을 지원합니다. MySQL은이를 지원하지만 대부분의 다른 데이터베이스에서는 작동하지 않습니다. –

+2

@TheJacobTaylor : MySQL에는 모든 그룹화 열이 필요하지 않습니다. 거의 모든 다른 DBMS가 SQL 표준을 따르고 있습니다. –

답변

33

사용 :

SELECT u.id, 
     u.name, 
     MIN(t.spent) AS spent 
    FROM USERS u 
    JOIN TRANSACTIONS t ON t.uid = u.id 
GROUP BY u.id, u.name 

하나 이상의 TRANSACTIONS 레코드가있는 사용자 만 반환한다는 사실을 기억하십시오. 당신은 당신이 돌아올 특정 행에 대해 걱정하지 않는 경우

SELECT u.id, 
      u.name, 
      COALESCE(MIN(t.spent), 0) AS spent 
    FROM USERS u 
LEFT JOIN TRANSACTIONS t ON t.uid = u.id 
GROUP BY u.id, u.name 
+0

+1 좋은, 나는 해결책을 생각해 내는데 어려움을 겪고 있었다. – northpole

+0

아! 당연하지. 때로는 근시로 보입니다. 한 가지 질문을 제외하고, 이전 버전의 MySQL에 자연스럽게 JOIN이 없었습니까? –

+0

예, 왼쪽 결합이라고합니다. :) 오른쪽 결합은 강제로 일치시킵니다. 왼쪽 조인에는 경기가 포함되지만 필요하지는 않습니다. – TheJacobTaylor

2

: 사용 - 당신은 지원 기록뿐만 아니라 할 사람이없는 사용자를 참조하십시오.

select id, name, spent 
from users 
left join transactions on users.id = transactions.uid 
group by id 

이렇게하면 사용자 당 하나의 행이 반환됩니다. 처음으로 일치하는 트랜잭션이됩니다.

건배, 야곱

0

나의 사과를이 실제로 귀하의 질문에 대답하지 않는 경우. 어떤 사용자에게 하나 이상의 트랜잭션이 있는지 확인하려는 것 같습니다. 이 작업을 수행하고 그 과정에서 각각의 사용자가이 같은 일을 지출 얼마나 많은 볼 수 있습니다 :

 
SELECT 
    u.id, 
    u.name, 
    SUM(t.spent) AS total 
FROM 
    USERS u 
    INNER JOIN TRANSACTIONS t 
     ON t.uid = u.id 
GROUP BY 
    u.id 
    , u.name 
+0

그들은 구체적으로 하나 또는 전혀 일치하는 것이 괜찮다고 말합니다. – TheJacobTaylor

+0

죄송합니다. "하나 이상의 것"으로 읽었습니다 – wshato

1

합리적인 답의 번호와, 동등한 최근의 질문에 대한 SO 3305709를 참조하십시오. 여기에 언급 된 DBMS는 Postgres이지만 차이점은 무시할 수 있습니다.

+1

'DISTINCT ON'은 Postgres에서만 지원되며, DISTINCT는 사용자 당 'spend'값이 다른 여러 행을 반환합니다. –

관련 문제