2017-12-01 27 views
1

내 앱은 users 테이블, teams 테이블, teams_users 테이블 및 assessments 테이블을 가지고 있습니다. 간단하게 :세 테이블을 결합하는 효율적인 쿼리

**users** 
id 

**teams** 
id 

**teams_users** 
team_id 
user_id 

**assessments** 
id 
user_id 
team_id 

사용자는 많은 평가를받을 수 있습니다.

나는 특정 상황에서 사용자를 잡아 때, 나는뿐만 아니라 (전체 대상) 관련 평가를 잡고 싶어 플러스 본질적으로 team_id 열을 뽑기의 결과 반환 된 사용자에 대한 값의 team_ids로 사용자의 user_idteams_users 테이블의 모든 행에 대해

나는 별도로 쿼리의 각 작업을 수행하는 방법을 알고,하지만 난 하나 개의 효율적인 쿼리로 결합 할 수 있으며, 더욱 확신이 그 작업을 수행하는 방법을 얼마나 내가 SQL 꽤 녹슬으로 나는 확신 해요 . 내 첫 번째 생각은 다음과 같았습니다.

SELECT users.id, users.name, users.email, users.role 
FROM users 
INNER JOIN assessments ON assessments.user_id = users.id 
WHERE users.id='someID' 

그런 쿼리에서는 실제로 평가를 수행하지 않습니다. 이 같은 그래서 고려하고 뭔가 :

SELECT users.id, users.name, users.email, users.role, assessments 
FROM users 
INNER JOIN assessments ON assessments.user_id = users.id 
WHERE users.id='someID' 

작품의 이런 종류의,하지만 값의 괄호로 구분 된 배열로 평가 반환 (I 자바 스크립트를 사용하고 있습니다를하고 pg 라이브러리는 달리 JSON으로 응답을 구문 분석) 이는이 JSON으로 파싱하는 것보다 SQL 수준에서 해결하기 위해 더 나은 것 같다

{ 
    id: 'mEPRVHp3', 
    name: 'Frank', 
    role: 'admin', 
    assessments: '(uibbH0ff,rPWZDIoA,mEPRVHp3,99,2017-12-01)' 
} 

명확히하기 위해, 나는 그렇게처럼 선호하는 것 :

{ 
    id: 'mEPRVHp3', 
    name: 'Frank', 
    role: 'admin', 
    assessments: [ 
    { 
     id: 'uibbH0ff', 
     team_id: 'rPWZDIoA', 
     user_id: 'mEPRVHp3', 
     score: 99, 
     date: '2017-12-01' 
    } 
    ] 
} 

을 다음 별도 같은 질문에 teams_usersteam_id을 들려주고 싶습니다. 최종 응답이 같은 있도록 : SELECT 문 끝에 teams_users.team_id AS team_ids을 추가하려고

{ 
    id: 'mEPRVHp3', 
    name: 'Frank', 
    role: 'admin', 
    assessments: [ 
    { 
     id: 'uibbH0ff', 
     team_id: 'rPWZDIoA', 
     user_id: 'mEPRVHp3', 
     score: 99, 
     date: '2017-12-01' 
    } 
    ], 
    team_ids: ['rPWZDIoA'] 
} 

하지만 전체 쿼리를 끊었다.

이 경우에도 가능하며,이 경우 모든 작업을 수행 할 수 있는지 확실하지 않습니다.

의견이 있으십니까? 내 제한된 SQL skillz 작업.

감사합니다.

답변

2

PostgreSQL 버전 9.3 이상을 사용한다고 가정합니다.

나는 row_to_json()을 사용하여 평가 기록을 형식화합니다. 그런 다음 측면 결합을 사용하여 팀 ID를 얻습니다. 그래서 같이

는 :

SELECT 
    usr.id, 
    usr.name, 
    usr.email, 
    usr.role, 
    row_to_json(asmnt) AS assessments, --Use row_to_json() 
    tusr.team_ids 
FROM 
    users usr 
INNER JOIN 
    assessments asmnt 
    ON asmnt.user_id = usr.id 
INNER JOIN LATERAL 
    (
    SELECT 
     array_agg(teams_users.team_id) AS team_ids 
    FROM 
     teams_users 
    WHERE 
     teams_users.user_id = usr.id 
    ) tusr 
    ON TRUE 
WHERE 
    usr.id = 'someID'; 
+0

이 굉장합니다! 정말 고마워! 하나의 이슈로 만듦 -'assessmentments'는 하나의 JSON 객체로 형식이 지정되었지만 (의미가 있음) 많은 사용자가 평가할 수 있습니다. 'array_to_json (asmnt)'을 시도했지만 함수가 아니라는 오류가 발생했습니다. 어떤 아이디어가 이것을 고치는 방법? 감사! – Sasha

+0

알았습니다! 'jsonb_build_array'는 매력처럼 작동했습니다! https://www.postgresql.org/docs/9.5/static/functions-json.html – Sasha