programing

왼쪽 조인(왼쪽 조인)

randomtip 2022. 12. 31. 16:46
반응형

왼쪽 조인(왼쪽 조인)

왼쪽 조인의 첫 번째 줄만 얻는 것에 대한 많은 스레드를 읽었지만, 어떤 이유에서인지 이 방법은 통하지 않습니다.

이것이 나의 구조입니다(물론 간략화).

피드

id |  title | content
----------------------
1  | Feed 1 | ...

아티스트

artist_id | artist_name
-----------------------
1         | Artist 1
2         | Artist 2

피드_프로세서

rel_id | artist_id | feed_id
----------------------------
1      |     1     |    1 
2      |     2     |    1 
...

이제 기사를 입수해서 첫 번째 아티스트에 참가하고 싶습니다.그리고 이런 생각을 했습니다.

SELECT *
    FROM feeds 
    LEFT JOIN feeds_artists ON wp_feeds.id = (
        SELECT feeds_artists.feed_id FROM feeds_artists
        WHERE feeds_artists.feed_id = feeds.id 
    LIMIT 1
    )
WHERE feeds.id = '13815'

feeds_module의 첫 번째 행만 가져오는데, 이미 이 기능은 작동하지 않습니다.

사용할 수 없습니다TOP데이터베이스로 인해 결과를 그룹화할 수 없습니다.feeds_artists.artist_id날짜별로 정렬해야 하기 때문에 (이렇게 그룹화하여 결과를 얻었지만 최신이 아닌 경우)

OUTER APPLY도 시도해 봤지만 역시 성공하지 못했다.솔직히 말해서 나는 그 줄에서 무슨 일이 일어나고 있는지 정말 상상할 수 없다 - 아마도 내가 이것을 작동시킬 수 없는 가장 큰 이유일 것이다.

해결책:

SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
    SELECT artist_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.id
    LIMIT 1
)
WHERE f.id = '13815'

아티스트 ID가 시간이 지남에 따라 증가한다고 가정할 수 있다면MIN(artist_id)가장 빠릅니다.

이와 같은 것을 시험해 보세요(미검증...)

SELECT *
  FROM feeds f
  LEFT JOIN artists a ON a.artist_id = (
    SELECT
      MIN(fa.artist_id) a_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.feed_id
  ) a

하위 선택 없는 버전:

   SELECT f.title,
          f.content,
          MIN(a.artist_name) artist_name
     FROM feeds f
LEFT JOIN feeds_artists fa ON fa.feed_id = f.id
LEFT JOIN artists a ON fa.artist_id = a.artist_id
 GROUP BY f.id

@Matt Dodges의 대답은 나를 올바른 길로 인도했다.그동안 많은 남자들에게 도움이 됐던 모든 답변에 다시 한 번 감사드립니다.다음과 같이 동작합니다.

SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
    SELECT artist_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.id
    LIMIT 1
)
WHERE f.id = '13815'

여기서 몇 가지 답변을 바탕으로 저는 제게 효과가 있는 것을 발견했고, 무슨 일이 일어나고 있는지 일반화하고 설명하고자 했습니다.

변환:

LEFT JOIN table2 t2 ON (t2.thing = t1.thing)

대상:

LEFT JOIN table2 t2 ON (t2.p_key = (SELECT MIN(t2_.p_key) 
    FROM table2 t2_ WHERE (t2_.thing = t1.thing) LIMIT 1))

t1과 t2를 접속하는 조건은 에서 이동한다.ON그리고 내면의 질문으로WHERE.그MIN(primary key)또는LIMIT 1는 내부 쿼리에 의해1 행만 반환되도록 합니다.

1개의 특정 행을 선택한 후, 우리는 그 행을ON어느 줄인지 그게 바로 그 이유야ON는 조인된 테이블의 프라이머리 키를 비교하고 있습니다.

내부 쿼리(즉, order+limit)를 사용할 수 있지만 원하는 행의 기본 키를 하나 반환해야 합니다.ON정확한 연결 열입니다.

업데이트 - MySQL 5.7 이상용

MySQL 5.7+와 관련된 또 다른 옵션은ANY_VALUE+GROUP BY. 반드시 첫 번째 이름이 아닌 아티스트 이름이 선택됩니다.

SELECT feeds.*,ANY_VALUE(feeds_artists.name) artist_name
    FROM feeds 
    LEFT JOIN feeds_artists ON feeds.id = feeds_artists.feed_id 
GROUP BY feeds.id

ANY_VALUE 상세:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

다른 것을 사용하고 있습니다(더 좋은 것 같습니다).

"group" 절이 있는 VIEW를 만들었습니다.

CREATE VIEW vCountries AS SELECT * PROVINCES GROUP BY country_code

SELECT * FROM client INNER JOIN vCountries on client_province = province_id

아직 말하고 싶은 건, 우리가 분석에서 뭔가 잘못했기 때문에 이 해결책을 취해야 한다는 거야... 적어도 내 경우에는...모든 것을 재설계하기 위해 이렇게 하는 게 더 저렴할 때도 있어요

도움이 됐으면 좋겠네요!

여기 절별 그룹화를 사용한 답변이 있습니다.

SELECT *
FROM feeds f
LEFT JOIN 
(
    SELECT artist_id, feed_id
    FROM feeds_artists
    GROUP BY artist_id, feed_id 
) fa ON fa.feed_id = f.id
LEFT JOIN artists a ON a.artist_id = fa.artist_id

나는 좀 더 일반적인 대답을 하고 싶다.LEFT JOIN의 첫 번째 항목만 선택할 경우 어떤 경우에도 처리할 수 있습니다.

원하는 것을 GROUP_CONCATS라고 하는 서브쿼리(소트도 가능)를 사용하여 GROUP_CONCAT'd 결과를 분할하고 첫 번째 항목만 가져올 수 있습니다.

LEFT JOIN Person ON Person.id = (
    SELECT SUBSTRING_INDEX(
        GROUP_CONCAT(FirstName ORDER BY FirstName DESC SEPARATOR "_" ), '_', 1)
    ) FROM Person
);

ORDER BY 옵션으로 DESC가 있으므로 "Zack"과 같은 사용자의 개인 ID가 반환됩니다."Andy"와 같은 이름을 가진 사람이 필요한 경우 ORDER BY First Name DESC를 ORDER BY First Name ASC로 변경합니다.

이는 주문 능력을 전적으로 사용자의 수중에 넣기 때문에 민첩합니다.그러나 많은 테스트를 거친 후 많은 사용자와 데이터가 있는 상황에서는 확장성이 떨어집니다.

단, 관리자에 대한 데이터 집약적인 보고서 실행에는 유용합니다.

DB2 Postgre SQL 키워드.LATERAL입니다.LEFT JOIN: (여기서는 DB2용)

SELECT f.*, a.*
FROM feeds f
LEFT JOIN LATERAL  
(
    SELECT artist_id, feed_id
    FROM feeds_artists sfa
    WHERE sfa.feed_id = f.id
    fetch first 1 rows only
) fa ON fa.feed_id = f.id
LEFT JOIN artists a ON a.artist_id = fa.artist_id

이것이 직접적인 해결책이 아니라는 것을 알지만, 저는 항상 이 문제에 직면했고, 왼쪽 조인 선택 등을 사용하면 데이터베이스와 서버에 큰 프로세스 비용이 들 수 있기 때문에 다음과 같이 php의 어레이를 사용하여 왼쪽 조인하는 것을 선호합니다.

먼저 두 번째 표에서 범위 내의 데이터를 가져오고 두 번째 표에서 한 행만 필요한 경우 결과 배열에 왼쪽 Join-In-Common 열을 키로 저장하십시오.

SQL1:

$sql = SELECT artist_id FROM feeds_artists fa WHERE fa.feed_id {...RANGE...}
    $res = $mysqli->query($sql);
if ($res->num_rows > 0) {
    while ($row = $res->fetch_assoc()) {
        $join_data[...$KEY...] = $row['artist_id'];
}

그런 다음 이전 배열에서 기본 데이터를 가져와 왼쪽 조인 테이블의 세부 정보를 추가하고 다음과 같이 가져옵니다.

SQL2:

$sql = SELECT * FROM feeds f WHERE f.id {...RANGE...};
$res = $mysqli->query($sql);
if ($res->num_rows > 0) {
    while ($row = $res->fetch_assoc()) {
        $key = $row[in_common_col_value];
        $row['EXTRA_DATA'] = $join_data[$key];
        $final_data[] = $row;
}

이제 $join_data 어레이에서 추가 데이터를 원하는 $final_data 어레이를 사용할 수 있습니다.이것은 일반적으로 날짜 범위 데이터와 이와 같이 작동합니다.

언급URL : https://stackoverflow.com/questions/15626493/left-join-only-first-row

반응형