Czytałem wiele wątków o uzyskiwaniu tylko pierwszego rzędu lewego łączenia, ale z jakiegoś powodu to nie działa dla mnie.
Oto moja struktura (oczywiście uproszczona)
Kanały
id | title | content
----------------------
1 | Feed 1 | ...
Artyści
artist_id | artist_name
-----------------------
1 | Artist 1
2 | Artist 2
feeds_artists
rel_id | artist_id | feed_id
----------------------------
1 | 1 | 1
2 | 2 | 1
...
Teraz chcę dostać artykuły i dołączyć tylko do pierwszego Artysty i pomyślałem o czymś takim:
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'
tylko po to, aby uzyskać tylko pierwszy wiersz feeds_artists, ale już to nie działa.
Nie mogę użyć z TOP
powodu mojej bazy danych i nie mogę grupować wyników według feeds_artists.artist_id
daty (mam wyniki, grupując je w ten sposób, ale wyniki nie były najnowsze)
Próbowałem też czegoś z OUTER APPLY - też bez sukcesu. Szczerze mówiąc, nie mogę sobie wyobrazić, co się dzieje w tych rzędach - prawdopodobnie jest to największy powód, dla którego nie mogę tego zrobić.
ROZWIĄZANIE:
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'
Odpowiedzi:
Jeśli możesz założyć, że identyfikatory wykonawców rosną w czasie, to
MIN(artist_id)
będzie najwcześniej.Więc spróbuj czegoś takiego (niesprawdzone ...)
źródło
Wersja bez podselekcji:
źródło
Odpowiedź @Matt Dodges postawiła mnie na właściwej drodze. Jeszcze raz dziękuję za wszystkie odpowiedzi, które w międzyczasie pomogły wielu chłopakom. Działa tak:
źródło
f.id
warunków.Użyłem czegoś innego (myślę, że lepiej ...) i chcę się tym podzielić:
Stworzyłem VIEW, który ma klauzulę „group”
Chcę jeszcze powiedzieć, że myślę, że musimy zrobić to rozwiązanie, PONIEWAŻ W ANALIZIE ZROBILIŚMY COŚ NIEPRAWIDŁOWEGO ... przynajmniej w moim przypadku ... ale czasami jest to tańsze, aby wszystko przeprojektować ...
Mam nadzieję, że to pomoże!
źródło
country_code
,GROUP BY
jest to niewłaściwe. ZobaczONLY_FULL_GROUP_BY
.WITH x AS (
klauzuli?Opierając się na kilku odpowiedziach tutaj, znalazłem coś, co zadziałało dla mnie i chciałem uogólnić i wyjaśnić, co się dzieje.
konwertować:
do:
warunek, który łączy t1 i t2, jest przenoszony z
ON
i do zapytania wewnętrznegoWHERE
.MIN(primary key)
iLIMIT 1
zapewnia, że tylko jeden rząd jest zwracany przez zapytanie wewnętrznej.po wybraniu jednego konkretnego wiersza musimy powiedzieć,
ON
który to wiersz. dlategoON
właśnie porównuje klucz podstawowy połączonej tabeli.możesz grać z wewnętrznym zapytaniem (tj. zamówienie + limit), ale musi ono zwrócić jeden klucz podstawowy żądanego wiersza, który wskaże
ON
dokładny wiersz do połączenia.źródło
LIMIT
lub tylkoMIN
.ON
warunek musi być na dołączył tabeli klucz podstawowy wpływ na wydajność uniknąć.Chcę udzielić bardziej ogólnej odpowiedzi . Taki, który poradzi sobie z każdym przypadkiem, gdy chcesz wybrać tylko pierwszy element w LEFT JOIN .
Możesz użyć podzapytania, które GROUP_CONCATS to, co chcesz (posortowane też!), A następnie po prostu podziel wynik GROUP_CONCAT i weź tylko jego pierwszy element, tak jak to ...
Ponieważ mamy DESC jako naszą opcję ORDER BY , to zwróci identyfikator osoby dla kogoś takiego jak „Zack”. Gdybyśmy chcieli kogoś o imieniu „Andy”, zmienilibyśmy ORDER BY FirstName DESC na ORDER BY FirstName ASC .
Jest to zwinne, ponieważ dzięki temu moc zamawiania jest całkowicie w Twoich rękach. Ale po wielu testach nie będzie dobrze skalować w sytuacji z dużą liczbą użytkowników i dużą ilością danych.
Jest to jednak przydatne do generowania raportów dla administratora zawierających duże ilości danych.
źródło
GROUP_CONCAT
sztuczka jest dobra, o ile liczba wartości jest ograniczona. Domyślny limit to 1024 znaków.