Dublowanie rekordów po left join

0

Mam widoki, z który chce wyciągnąć dane. Chce mieć połączone dane.
Tabela A wygląda:
Indeks ilość
aaa 1
bbb 2
ccc 3
ddd 4 itd

Tabela B wygląda
Indeks kolor
aaa bialy
aaa bialy
bbb czarny
bbb czarny
ccc zielony
ddd niebieski

select A.indeks,a.ilosc,b.kolor from tabelaA 
left join tabelaB on a.indeks=b.indeks 

Problem polega na tym że dla indeksów aaa, bbb, które są podwójnie w tabeli B dostaję podwójne rekordy.
Jak się przed tym zabezpieczyć?

0

Nie jestem przekonany, jaki efekt chcesz osiągnąć.
Czy przećwiczyć złączenie JOIN, czy wybrać dane? :)
Nie wiem także, na jakim motorze bazy danych pracujesz, ale jeżeli jest to MySQL, to zadziała takie coś

SELECT 
  TableA.`indeks` AS klucz, 
  TableA.`ilosc`,  
  TableB.`kolor` 
FROM TableA, TableB
WHERE TableA.`indeks` = TableB.`indeks` GROUP BY klucz

To też powinno zadziałać:

SELECT 
  TableA.`indeks` AS klucz, 
  TableA.`ilosc`, 
  (SELECT TableB.`kolor` FROM TableB WHERE TableB.`indeks` = klucz GROUP BY `indeks`)
FROM TableA

oraz to również:

SELECT 
  TableB.`indeks` AS klucz, 
  TableB.`kolor`, 
  (SELECT TableA.`ilosc` FROM TableA WHERE TableA.`indeks` = klucz )
FROM TableB GROUP BY klucz

Zwróć proszę uwagę na to, że klauzula GROUP BY po jakimś polu powoduje, że wybrane wartości są unikalne w tej kolumnie.
Teraz już dowolnie, czy najpierw wybierzesz dane z tabeli B i spowodujesz, że nie będą się dublowały wartości (dodając GROUP BY na indeks, czy też wybierzesz w pierwszej kolejności dane z tabeli A i uzupełnisz je informacjami z tabeli B

Mała rada na przyszłość:

  1. Nie używaj polskich "ogonków" w nazwach tabel i kolumn (iloŚĆ),
  2. Nie używaj nazw "niebezpiecznych" ;-) w nazwach tabel i kolumn (np "index")

I jeszcze jedno, gdy tak patrzę na te tabele i ich zawartość.
Sądzę, że powinieneś połączyć je w jedną tabelę (kolumnaIndex, KolumnaKolor, KolumnaIlosc) i zadeklarować KolumneIndex jako klucz główny (PK) . Wydaje mi się, że wskazane byłoby także, by kolumna z kolorami była unikalna.

....Ale nie wiem do czego to stosujesz i jakie masz potrzeby, więc potraktuj to jako luźne propozycje ;-)

Oops! :(
Zauważyłem, że stoi znaczek "oracle" przy Twoim poście, więc mój wtręt "nie wiem, na jakiej bazie pracujesz" jest lekko nieaktualny ;-) ....ale sądzę, że moje zapytania na tym motorze też zadziałają.

Na marginesie, Twój przykład:

SELECT A.indeks,a.ilosc,b.kolor FROM tabelaA 
LEFT JOIN tabelaB ON a.indeks=b.indeks 

zmodyfikowałbym:

SELECT a.`indeks`, a.`ilosc`, b.`kolor` FROM tabelaA a 
LEFT JOIN TabelaB b ON a.indeks = b.indeks
GROUP BY `indeks`

a jak się głębiej temu przyjrzysz, to zwrócisz uwagę, że na Twoje potrzeby (unikalności po kolumnie indeks) nie ma znaczenia, czy wykonujesz złączenie lewostronne (LEFT) czy prawostronne (RIGHT).

Dla aktualnej zawartości tabel A i B, poniższy kod też powinien dać ten sam efekt, co we wcześniejszym przykładzie

SELECT a.`indeks`, a.`ilosc`, b.`kolor` FROM tabelaA a 
RIGHT JOIN TabelaB b ON a.indeks = b.indeks
GROUP BY `indeks`

.... i samo JOIN też chyba zaskoczy (... tak na 99,99% ;-))

SELECT a.`indeks`, a.`ilosc`, b.`kolor` FROM tabelaA a 
JOIN TabelaB b ON a.indeks = b.indeks
GROUP BY `indeks`
0

Wiesz te tabele były tylko na zasadzie przykładu i wyglądają one zupełnie inaczej. W rzeczywistości mam jedną tabelą, w której mam indeks, nazwa_klienta, ilosc, wartosc i wiele innych danych sprzedażowych oraz drugą bazę, w której do każdego indeksu przypisane są różne cechy takie jak kolor, kształt, format, grubość i ilość dostępna na magazynie. itp. ale indeksy te powtarzają się przez wzgląd ze występują na różnych magazynach pozostałe cechy są identyczne, czyli jeśli produkt leży na pięciu magazynach to jest 5 rekordów takich samych różniących się tylko magazynem i ilością dostępną.
Chcę np. wyciągnąć dane o wielkości sprzedaży np. Indeksów dla których produkty są żółte i niebieskie to chcę dociągnąć kolor, ale tu pojawia się problem, że jeśli
indeksu aaa sprzedało się 10szt to po join -ie koloru, jeśli ten produkt jest na 4 magazynach robią się cztery rekordy
aaa 10 zołty
aaa 10 zołty
aaa 10 zołty
aaa 10 zołty
Jeśli produkt jest tylko na jednym magazynie problem ten nie występuje.
Także group by tu nic nie da, bo zwinie mi to do jednego rekordu tu zgoda, ale ilość którą otrzymam to 40, a naprawdę sprzedało się 10.
Na tym polega mój kłopot.

0

To może zrób jedną bazę dla wszystkich magazynów i dodaj kolumnę z nr_magazynu do tabeli.
I do tego stwórz triggera, który będzie automatycznie dla każdego magazynu dodawał numer magazynu.
Spróbuj tęz pokombinować z DISTNICT.

0
bizzy napisał(a):

Wiesz te tabele były tylko na zasadzie przykładu i wyglądają one zupełnie inaczej......

Wiesz....
Ustosunkowałem się do Twojego problemu podwójnych wystąpień po Selekcie dla struktur i danych, które przedstawiłeś.
Mam nadzieję, że moje przykłady były jasne i wyczerpujące. :)

Nie znam struktury Twojego magazynu i w związku z tym nie podejmuję się dalszego sugerowania czegokolwiek. :(

Pozdrawiam i powodzenia.

0

A żeby nie było, że tylko krytykuję:

SELECT A.indeks,a.ilosc,b.kolor FROM tabelaA a
LEFT JOIN (SELECT DISTINCT Indeks, kolor FROM tabelaB) b ON a.indeks=b.indeks 
0

Tak na marginesie, zechcesz się podzielić wiedzą, czym różni się Twoje zapytanie od mojego:

SELECT
TableA.indeks AS klucz,
TableA.ilosc,
(SELECT TableB.kolor FROM TableB WHERE TableB.indeks = klucz GROUP BY indeks)
FROM TableA

Chętnie zapoznam się z "kluczowymi różnicami" (szczególnie gdy wyświetlisz explain query) dla fragmentów
SELECT DISTINCT Indeks, kolor FROM tabelaB - w Twoim zapytaniu
(SELECT TableB.kolor FROM TableB WHERE TableB.indeks = klucz GROUP BY indeks) - i w moim

0
BSorbus napisał(a):

Tak na marginesie, zechcesz się podzielić wiedzą, czym różni się Twoje zapytanie od mojego:

SELECT
TableA.indeks AS klucz,
TableA.ilosc,
(SELECT TableB.kolor FROM TableB WHERE TableB.indeks = klucz GROUP BY indeks)
FROM TableA

To jest zapytanie skorelowane, które wykonane zostanie dla każdego wiersza z TableA. I to nie jest fajne...
@Marcin.Miga pokazał inny sposób - złączenie jest wykonane do wyniku, który odrzuca powtórzone rekordy.

Także, jego wersja powinna być szybsza - ale wiele zależy od silnika bazy danych...
Chętnie zapoznam się z "kluczowymi różnicami" (szczególnie gdy wyświetlisz explain query) dla fragmentów
SELECT DISTINCT Indeks, kolor FROM tabelaB - w Twoim zapytaniu
(SELECT TableB.kolor FROM TableB WHERE TableB.indeks = klucz GROUP BY indeks) - i w moim

Rożnica jest opisana na górze, a generalnie nalezy unikać takich konstrukcji jak Twoja.
Są naprawdę lepsze sposoby.
Tak na marginesie - żaden podany w tym wątku nie wyczerpuje pytania i każdy posiada błędne założenie.
Dlaczego wychodzicie od TabelaA skoro powinno się wyjść od TabelaB, bo tam są istotne dane o sprzedaży?

@bizzy, możesz dokładnie wyjaśnić co masz na myśli pisząc:

Jeśli produkt jest tylko na jednym magazynie problem ten nie występuje.
Także group by tu nic nie da, bo zwinie mi to do jednego rekordu tu zgoda, ale ilość którą otrzymam to 40, a naprawdę sprzedało się 10.

Jak jednoznacznie określić że coś się sprzedało? Ja rozumiem to tak, że Ty chcesz dostać dane które się sprzedały - czyli dokładnie jak wybrałbyś (jakie muszą spełnić warunki) takie dane z TabelaB?
A więc najpierw należy wybrać to co się sprzedało z TabelaA a dopiero potem dołączyć dane z TabelaB.

0

"....To jest zapytanie skorelowane, które wykonane zostanie dla każdego wiersza z TableA. I to nie jest fajne..."
Dogmatycznie podchodząc do sprawy masz 100% racji, ale.....
Zostanie wykonane dla każdego WYBRANEGO wiersza, bo chyba nie mamy wątpliwości, że nakładając warunek WHERE TabelaA coś tam, nie zostanie wykonane DLA KAŻDEGO wiersza z całej TableA, tylko dla każdego wiersza z WYBRANEGO kursora.

" .....co przy założeniu Twoim (i moim!): "A więc najpierw należy wybrać to co się sprzedało z TabelaA a dopiero potem dołączyć dane z TabelaB. winno dać oczekiwany efekt."

  • zatem chyba właśnie takiego efektu oczekujemy? ;-)

"@Marcin.Miga pokazał inny sposób - złączenie jest wykonane do wyniku, który odrzuca powtórzone rekordy.
Także, jego wersja powinna być szybsza - ale wiele zależy od silnika bazy danych..."

  • Dobrze byłoby gdyby jego wersja faktycznie odrzucała powtórzone rekordy w TabeliA.
    Jego zapytanie nie jest odporne na to, a to właśnie zarzucił mojemu "gorszemu" rozwiązaniu.

"Tak na marginesie - żaden podany w tym wątku nie wyczerpuje pytania i każdy posiada błędne założenie.
Dlaczego wychodzicie od TabelaA skoro powinno się wyjść od TabelaB, bo tam są istotne dane o sprzedaży?"

  • Może dlatego, że zapytanie tak zostało skonstruowane?
    Zwróć proszę uwagę na fakt, że głównym zmartwieniem pytającego były zdublowane "aaa biały, bbb czarny" na liście wyników, temat brzmi "Dublowanie rekordów po left join",
    .....a nie stawia on pytania, jak elegancko policzyć sprzedane towary...

"Jak jednoznacznie określić że coś się sprzedało? Ja rozumiem to tak, że Ty chcesz dostać dane które się sprzedały"

  • założenie może i słuszne, ale jeżeli kolega chce dostać też listę z pozycjami "= 0" sprzedaży?

1 użytkowników online, w tym zalogowanych: 0, gości: 1