Adam Kowalski

Adam Kowalski Specjalista ds
Analiz Rynkowych,
Kompania Piwowarska
S.A.

Temat: JOIN i wybieranie tylko jednego pasującego rekordu (duble)

Witam,
przyznam, że mam nie lada problem. Korzystam z tabeli, gdzie pewne dane są w formacie.
id, status, data_od, data_do

W teorii dla jednego id i statusu, daty nie powinny się nakładać, tzn. powinny być np. w formie:

daty:
id| status | data od | data do
1 | aktywny | 2016-03-10 | 2016-03-13
1 | aktywny | 2016-03-14 | 2016-03-30

Problem w tym, że użytkownicy nie zawsze się stosują do zasady i potrafią wpisać "datę do" np. 2016-03-13 i w kolejnym rekordzie "datę od" również 2016-03-13 (nie mam tu żadnych możliwości zmian, tylko odczytuję), co powoduje, że przy szukaniu pokrewnych rekordów dla daty występującej w moich danych, np:
 
... LEFT JOIN on daty.id = moje.id and '2016-03-13' between daty.data_od and daty.data_do

mam duble - serwer (słusznie z resztą) wyświetla dwa pasujące rekordy.
Nie bardzo mogę zrobić tu subzapytanie grupujące, bo (o ile mi wiadomo) tak wstawione pola daty są dla serwera różne, poza tym trafiają się też innego rodzaju nałożenia dat - np. dla tego samego ID są dwa rekordy i data końcowa jest taka sama, a data początkowa już różna. W przypadku wstrzelenia się w datę, która pasuje do obu rekordów - będzie znowu dubel..
Idealny byłby dla mnie ogranicznik JOIN do pierwszego znalezionego rekordu (coś jak LIMIT 1), bo nie jest dla mnie istotne, który z nich bym zastosował - każdy z wyników jest dobry, o ile występuje tylko raz :)
Jedyny pomysł jaki mi przychodzi to już w wynikowym zapytaniu zastosować ROW_NUMBER OVER.. i ograniczyć do nr "1". A czy da się to ograniczyć na poziomie JOINa?

konto usunięte

Temat: JOIN i wybieranie tylko jednego pasującego rekordu (duble)

Dobrym pomysłem jest wpisanie bazy w tytule posta. Ponieważ nie podane, wiec powiem jak to jest w Postgresie. Dałbym w where between, żeby wybrać przedziały i w select distinct on (id, status), żeby mieć pewność, że weźmie jedno wystąpienie. No i dałbym trigger, zweryfikuje czy rekord spełnia kryteria. Jak przedziały się nakładają - wywaliłbym błąd.
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: JOIN i wybieranie tylko jednego pasującego rekordu (duble)

Jeżeli tylko możesz robić select to najprościej ale nie najpoprawniej:
SELECT id, status, MAX(data_od), MAX(data_do) GROUP BY id, status;
Zawsze walnie jeden wiersz najprawdopodobniej ostatni. Wyjątkiem będzie tylko taki zestaw gdzie przedział jednego wiersza zawiera się w drugim.

konto usunięte

Temat: JOIN i wybieranie tylko jednego pasującego rekordu (duble)

Oj... To ja już bym wolał dać tego distincta:

SELECT distinct on (id, select) id, status, data_od, data_do ...

Nawet jak przedziały się przetną - nie będzie problemu. Co jak nie ma distinct on?
Można tak:

SELECT id, status, data_od, data_do
FROM table
WHERE (id,status) = (SELECT t.id, t.status FROM table t GROUP BY t.id, t.status)

Tak tylko się SQLem popisuję :)
Marcin Mackiewicz

Marcin Mackiewicz Programista JAVA, RS
Adware Polska

Temat: JOIN i wybieranie tylko jednego pasującego rekordu (duble)

Tak na prawdę to powinno być zrobione zabezpieczenie na (t)opornych użytkowników. Dwa razy zrobi źle to się nauczy. DISTINCT jak najbardziej tak.

Następna dyskusja:

mySQL -pobieranie danych z ...




Wyślij zaproszenie do