[mysql] 왼쪽 만 첫 번째 행

왼쪽 조인의 첫 번째 행만 얻는 것에 대한 많은 스레드를 읽었지만 어떤 이유로 든 작동하지 않습니다.

여기 내 구조가 있습니다 (물론 단순화 됨)

피드

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

예술가

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

feeds_artists

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_artists의 첫 번째 행만 가져 오지만 이미 작동하지 않습니다.

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'


답변

나는 다른 것을 사용했고 (더 나은 생각 …) 공유하고 싶습니다.

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

CREATE VIEW vCountries AS SELECT * PROVINCES GROUP BY country_code

SELECT * FROM client INNER JOIN vCountries on client_province = province_id

나는 아직 우리가 분석에 잘못 되었기 때문에이 솔루션을 수행해야한다고 생각합니다. 적어도 제 경우에는 …하지만 때로는 모든 것을 다시 디자인하기 위해이 작업을 수행하는 것이 더 저렴합니다 …

도움이 되길 바랍니다!


답변

여기에 몇 가지 대답을 바탕으로, 나는 나를 위해 일한 것을 발견했고 무슨 일이 일어나고 있는지 일반화하고 설명하고 싶었습니다.

변하게 하다:

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 행은 내부 쿼리에서 반환되어 있는지 확인하십시오.

하나의 특정 행을 선택한 후 ON어떤 행 인지 알려야합니다 . 그 이유는ON 조인 된 테이블의 기본 키를 비교하는 입니다.

내부 쿼리 (예 : order + limit)로 재생할 수 있지만 원하는 행의 기본 키 하나를 반환 ON하여 정확한 행을 조인해야합니다.


답변

보다 일반적인 답변 을 드리고 싶습니다 . LEFT JOIN의 첫 번째 항목 만 선택하려는 경우 를 처리 합니다 .

GROUP_CONCATS 하위 쿼리를 사용하여 원하는대로 정렬 한 다음 GROUP_CONCAT의 결과를 분할하고 첫 번째 항목 만 가져갈 수 있습니다.

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 FirstName DESCORDER BY FirstName ASC로 변경합니다. 합니다.

이것은 주문의 힘을 당신의 손 안에 맡기므로 민첩합니다. 그러나 많은 테스트를 거친 후에 는 확장 성이 떨어집니다. 사용자와 많은 데이터가있는 상황에서는 .

그러나 관리자를 위해 데이터 집약적 보고서를 실행하는 데 유용합니다.


답변