Składanie dwóch zestawów danych

Składanie dwóch zestawów danych
JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5052
0

Cześć, mam tabelę z ustawieniami. Jest jedno pole, nazwijmy je PID, które przyjmuje wartość NULL lub konkretne ID klienta.
Tabela może wyglądać tak:

PID Name Value
NULL Setting1 0
NULL Setting2 1
1 Setting1 1

I teraz tak. Jeśli PID = NULL, to jest to jakieś ustawienie domyślne. Klient nie nadpisał go. Teraz chciałbym utworzyć takiego SELECTa, który zwróci mi pełen zestaw ustawień, gdzie ważniejszym będzie to dla konkretnego klienta. Czyli w tym wypadku powinienem dostać (dla klienta o PID = 1):

Setting1 = 1
Setting2 = 1 (domyślne)

Jak skonstruować takiego selecta?
SZBD to MariaDB

Patryk27
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
  • Postów: 13042
0

unionem może?
Coś w deseń: select * where pid=null union select * where pid=1.

JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5052
0

Myślałem o UNION, ale tu będę miał dwa zestawy danych. Domyślne ustawienia i te dla konkretnego klienta. A chciałbym tego uniknąć. Próbuję kombinować coś w ten deseń:

Kopiuj

SELECT MAX(PID), name, value
FROM settings
WHERE PID = 1 or PID = 0
group by name

(tymczasowo NULL zmieniłem na 0)
ale to nie działa. Dostaję głupie wyniki.

abrakadaber
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6610
2
Kopiuj
select * from tab t1 where pid = x
union
select * from tab t2 where pid is null and not exists (select 1 from tab t3 where t3.pid = x and t2.name = t3.name)

ale po co tak kombinujesz - bierzesz wszystkie dla usera i do tego domyślne, których user nie ma i po zawodach

OV
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 19
0

Jeśli dobrze zrozumiałem to co chcesz wyciągnąć, to zabrałbym się za to w ten sposób:

Kopiuj

select a.*, b.value

from ( select max(pid) pid, name from settings group by name ) a

left join (select name, value from settings group by name, value) b
on a.name = b.name

JU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5052
0

No tak właśnie chcę. Wszystkie dla usera i domyślne, których user nie ma ;) Wymyśliłem jeszcze coś takiego:

Kopiuj
select i.pid, i.name, s.value
from
(
    SELECT MAX(pid) as pid, name
    FROM settings
    WHERE pid= 1 or pid = 0
    group by name
) as i
LEFT JOIN settings s on s.pid = i.pid and s.name = i.name

Muszę porównać te dwa zapytania.

YA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2399
0

Szybkie google mówi, że MariaDB wspiera funkcje analityczne, moja propozycja:

Kopiuj
select name,value from (
select row_number() over (partition by name order by pid nulls first) as rn,name,value from tabelka where (pid=:pid or pid is null)
) where rn=1;
  1. Wyciągamy rekordy dla danego ziomka (pid =:pid) + domyślne (pid is null)
  2. Tak wyciągnięty zbiór dzielimy na podzbiory (po nazwie)
  3. Podzbiory sortujemy po pidzie, tak by pid null był na początku
  4. Elementy każdego podzbioru numerujemy
  5. Wyciągamy elementy o numerze = 1

-- Drobna poprawka: NULLS first

abrakadaber
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6610
0

no to teraz test co jest szybsze i ogłoszenie zwycięzcy :p

PA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 3902
0

Można też join-em, czyli pobieram cały zestaw domyślnych wartości d.pid is null i dołączam te skonigurowane przez użytkownika.

Kopiuj
Select
    d.name
    IFNULL(u.value,d.value) as Value
from
    tabela as d
    left join tabela as u on d.name=u.name and u.pid=1
where
    d.pid is null

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.