Składanie dwóch zestawów danych

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

0

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

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ń:


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.

2
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

0

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


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

0

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

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.

0

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

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

0

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

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.

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

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