왼쪽 조인(왼쪽 조인)
왼쪽 조인의 첫 번째 줄만 얻는 것에 대한 많은 스레드를 읽었지만, 어떤 이유에서인지 이 방법은 통하지 않습니다.
이것이 나의 구조입니다(물론 간략화).
피드
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
'programing' 카테고리의 다른 글
Pythons 타임릿을 사용하여 성능을 테스트하기 위한 코드 세그먼트를 어떻게 시간을 잴 수 있습니까? (0) | 2022.12.31 |
---|---|
Python에서 파일을 읽고 쓰는 Unicode(UTF-8) (0) | 2022.12.31 |
MySQL에서 파라미터를 사용하여 뷰를 작성할 수 있습니까? (0) | 2022.12.31 |
최대 절전 모드에서 열거형을 문자열에 매핑하는 중 (0) | 2022.12.31 |
기본 키가 존재하지 않는지 확인하는 동안 리퀴베이스가 실패함 (0) | 2022.12.31 |