Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: SQL dotaz pro získání nesplněných hlasování

Aktivity
Avatar
Jiří Hrdina:24.7.2019 0:38

Ahoj,
snažím se přijít na vhodný SQL dotaz, který by mi zajistil: (viz obrázek, kde je Mysql diagram s entitami)
Potřebuji získat všechny eventy, které daný uživatel ještě neviděl (respektive nevolil). Zároven potřebuji, aby bylo bráno v potaz to, že ten daný event musí být sdílen s daným uživatelem. K tomu slouží ta tabulka users_events.

Mockrát děkuji za případné rady

Zkusil jsem: Šel jsem na to pomocí tohoto:JPQL dotazu
"SELECT e FROM Event e JOIN e.users u WHERE u.votes IS EMPTY AND u.email = :email"
Což nefunguje, ale tímhle podobným stylem by mělo být řešení si myslím.

 
Odpovědět
24.7.2019 0:38
Avatar
Martin Konečný (pavelco1998):24.7.2019 1:04

Ahoj, můžeš zkusit něco takovýho, psal jsem to z hlavy, takže nevím, jestli to bude úplně OK.

SELECT * FROM event
INNER JOIN user_events ON user_events.event_id = event.id
INNER JOIN user ON user_events.user_id = user.id
LEFT JOIN pool_option ON pool_option.event_id = event.id
LEFT JOIN vote ON vote.pool_option_id = pool_option.id
WHERE pool_option.id NOT IN (
  SELECT id
  FROM pool_option
  WHERE user_id = user.id
)

V podstatě vybírám všechny eventy, které jsou sdílené s uživatelem (ty první dva INNER joiny), pak nezávisle na tom připojuji hlasování (dva LEFT joiny) a omezím záznamy hlasování podle té podmínky WHERE NOT IN, ve kterém vyberu hlasování, které již uživatel dal.

Nejsem si z hlavy jistý, jestli to s těmi LEFT bude fungovat a zda by místo nich taktéž neměl být INNER, ale nejsem si jistý, jak by se to popralo s těmi prvními dvěma joiny :D

Editováno 24.7.2019 1:04
Nahoru Odpovědět
24.7.2019 1:04
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Jiří Hrdina:24.7.2019 10:57

Děkuji. Bohužel dotaz nefunguje.

Když jsem zkusil přímo tvůj kod, tak mi píše, že used_id ve WHERE je dvojznačký.
Poté jsem změnil tu WHERE část takto:

SELECT * FROM event
INNER JOIN users_events ON users_events.event_id = event.id
INNER JOIN user ON users_events.user_id = user.id
LEFT JOIN pool_option ON pool_option.event_id = event.id
LEFT JOIN vote ON vote.pool_option_id = pool_option.id
WHERE pool_option.id NOT IN (
  SELECT po.id
  FROM pool_option po
  join vote ON vote.pool_option_id = po.id
  WHERE vote.user_id = 4
)

To sice nevyhodí chybu, ale nevrací mi to vůbec nic (ačkoli by mělo).

 
Nahoru Odpovědět
24.7.2019 10:57
Avatar
Jiří Hrdina:24.7.2019 11:11

Ne, tak se omlouvám. Jsem neměl testovací data v té tabulce users_events.
Nicméně ten můj sql dotaz samozřejmě nevyhodí eventy, které uživatel neviděl, ale spíše něco, co uživatel nevolil (tedy tu druhou možnost ,než volil). Ale nevrátí mi to jeho nevolené eventy.

 
Nahoru Odpovědět
24.7.2019 11:11
Avatar
Odpovídá na Jiří Hrdina
Martin Konečný (pavelco1998):24.7.2019 11:36

Pokud to píše, že nějaký sloupec je "ambigous", pak by mělo stačit si jen u některé tabulky udělat alias.
Nešlo by to s tím WHERE takhle?

WHERE pool_option.id NOT IN (
  SELECT po.id
  FROM pool_option po
  WHERE po.user_id = user.id
)

Případně pokud to není chyba v tom WHERE, ale v SELECT, můžeš pro zkoušku napsat

SELECT event.* FROM event
Editováno 24.7.2019 11:37
Nahoru Odpovědět
24.7.2019 11:36
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Jiří Hrdina:24.7.2019 11:42

Problém je, že v té tabulce pool_option nemám to user_id... čili tam se ta where musí udělat jinak :(

SELECT * FROM event
INNER JOIN users_events ON users_events.event_id = event.id
INNER JOIN user ON users_events.user_id = 4
LEFT JOIN pool_option ON pool_option.event_id = event.id
LEFT JOIN vote ON vote.pool_option_id = pool_option.id
WHERE pool_option.id NOT IN (
  SELECT po.id
  FROM pool_option po
  JOIN vote v ON po.id = v.pool_option_id
  WHERE v.user_id = 4
)
;

udělal jsem to takhle, ale vyhazuje to prostě všechny varianty, které ten daný uživatel nevolil.

Editováno 24.7.2019 11:44
 
Nahoru Odpovědět
24.7.2019 11:42
Avatar
Odpovídá na Jiří Hrdina
Martin Konečný (pavelco1998):24.7.2019 12:58

Jasné, promiň, jsem se trošku zamotal a zapomněl, že v pool_option to user_id není :D Nicméně s tím JOINem v subselectu se mi to zdá OK.

Zadání je: "Potřebuji získat všechny eventy, které daný uživatel ještě neviděl (respektive nevolil)"
A tento SQL dotaz vrací nejen eventy, ale všechny varianty hlasování?
Pokud ano, můžeš zkusit ještě GROUP BY event.id nebo tak něco, aby se to seskupilo dle těch eventů.

Nahoru Odpovědět
24.7.2019 12:58
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Jiří Hrdina:24.7.2019 13:24

Díky, vypadá to, že následující SQL dotaz je funkční

SELECT * FROM event
INNER JOIN users_events ON users_events.event_id = event.id
INNER JOIN user ON users_events.user_id = 4
LEFT JOIN pool_option ON pool_option.event_id = event.id
LEFT JOIN vote ON vote.pool_option_id = pool_option.id
GROUP BY event.id
HAVING vote.id is null
;

Zkoušel jsem to jen na rychlo a vypadá to nadějně. Zkusím to potom později pořádně, jestli to funguje, ale vypadá to, že jo :-)
Díky za pomoc :-)

 
Nahoru Odpovědět
24.7.2019 13:24
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.