Wpis z mikrobloga

#programowanie #sql mam prostą relację jeden-do-wielu. W tabeli rodziców są jakieś tam dane - potrzebuję wszystkich. W tabeli dziecka mam jedną kolumnę z dużą ilością tekstu ale potrzebuję tylko 45 pierwszych znaków i nie potrzebuję żanych innych danych z tej tabeli. Tzn. chcę mieć na wyjściu rodzica z listą skróconych wartości ze wszystkich tabeli dzieci.

Mogę zrobić procedurę, że po otrzymaniu ID rodzica, query mi zwróci tabelkę z jedną kolumną varchar(45) i tyle ale mam wtedy dużo zapytań bo najpierw biorę wszystkich rodziców, a później dla każdego z nich pytam o tę procedurę... dlatego nie wiem czy to jest dobre rozwiązanie.

Z drugiej strony jak dam JOIN to dostanę wieeelką tabelę z danymi rodzica powtarzanymi np. 100 razy... oczywiście sobie tam w programie wywalę co niepotrzebne ale nie wiem co lepiej... A czy B? chyba, że jest jeszcze jakaś trzecia opcja... :P
  • 15
@Taczi: @kontrowersje: Mam tabelę RODZICE. Mam tabelę DZIECI. Każdy rodzic ma wiele dzieci. Każdy rodzic ma dużo kolumn z danymi. Każde dziecko ma dużo kolumn z danymi. Potrzebuję wszystkich rodziców i wszystkich danych rodziców ale tylko listę dzieci, bez danych dzieci. Nazwy dzieci mają od #!$%@? znaków więc trzeba je przyciąć.
@qtsms: Ogólnie, uniwersalnym rozwiązaniem są dwa zapytania zamiast joina.
U mnie w pracy mamy temp table, do którego wstawiamy dane rodziców i potem wysyłamy do klienta najpierw wszystkie dane rodziców, a potem joina "id rodzica" z danymi dziecka, a klient robi joina na danych korzystając z sortowania kubełkowego.
Sprawdza się przy przepustowości połączenia baza-klient rzędu 50kB/s (niska jakość rozwiązania oferowana przez Microsoft Azure).
A co gdyby select a, b from (select distinct * from rodzic) join dziecko


@Taczi: z distinct mam jedną listę, a potrzebuję osobnej listy dla każdego rekordu.

@Ginden: MySQL, community.

Może źle to opisałem... lepiej na życiowym przykładzie. Screen jest bardzo uproszczony ale nieważne. Czy lepiej:
1) SELECT Meetings.name, Meetings.date, LEFT(Topics.name, 45) FROM Meetings LEFT JOIN Topics ON Meetings.id = Topics.Meetings_id;
2) SELECT * FROM Meetings; i dla każdego otrzymanego
q.....s - > A co gdyby select a, b from (select distinct * from rodzic) join dziecko
...

źródło: comment_GXnNvOY55awYvGiQoYTZt0howl6Hz71o.jpg

Pobierz
@qtsms: zależy od problemu - co chcesz później z tym zrobić?

Jeżeli jakiś agregat i idziesz w stronę hurtowni danych, to opcja nr 1, hash-join'y, parallelism etc.
Jeżeli chcesz z takimi danymi coś w międzyczasie zrobić, to pozostaje tylko opcja nr 2.
Jeżeli ma to być system OLTP (zwykły, operacyjny), to opcja nr 1 i upewnienie się, że indeksy są wszędzie tam, gdzie trzeba.
Dla rozwiązania pierwszego dostanę Meetings.name i Meetings.date tyle razy ile jest rekordów w tabeli Topics, a nie tyle razy ile jest w tabeli Meetings czyli dużo razy... zakładając, że w tej tabeli nie będzie tylko tych dwóch kolumn, a dużo więcej i np. także stringi, a nie tylko ładne cyferki to otrzymam wielką paczkę danych gdy potrzebuję tylko małej częsci.

Z drugiej strony, osobne pytanie dla każdego rekordu Meetings spowolni cały proces
@Ginden: nie rozumiem twojego rozwiązania. (1) Tworzę tabelę tymczasową identyczną jak tabela Meetings, (2) wsadzam do niej dane z oryginalnej tabeli Meetings, (3) wybieram wszystko z tej tymczasowej tabeli ((A) dlaczego nie robię SELECT na oryginalnej tabeli i (B) co z tym robię?), a na koniec (4) wybieram wszystkie rekordy z tabeli Topics których klucze znajdują się w tej tymczasowej, identycznej z oryginalną tabeli... czyli wszystkie. Zupełnie nie czaję... chyba, że
@qtsms: Pominąłem elementy dwa - do tabeli tymczasowej wkładasz tylko te wiersze, które chcesz. Jeśli nie robisz WHERE lub jest on nieskomplikowany to możesz zrobić bezpośrednio z tabeli.