SQL finomságok

Mindig tanul az ember valamit.

Most például azt, hogy a CASE működik COUNT-on belül, és ORDER BY feltételben is.

A task rekordok korábbi állapota a task_history-ban vannak, LEFT JOIN-nal párosítsuk össze őket, melyik rekordnak hány korábbi értéke van:

SELECT uuid, COUNT(th.task_uuid) AS history_count
FROM tasks t 
LEFT JOIN task_history th 
ON t.uuid=th.task_uuid 
GROUP BY t.uuid;
uuid      history_count
--------  -------------
cea2c25f  1 
a1b50896  2 
c5cb739a  4 
de5860ae  0 
e65cee3f  0 
ecbe2ad3  5 
ecbfdd61  0 
fae35a3b  4 

Egy ilyen history bejegyzéshez opcionálisan lehet megjegyzést is fűzni, a feladat valójában az lenne, hogy a kilistázott feladatoknál jelenítsük meg a kommentek számát.

A HAVING nem jó, mert az a csoportba szervezés feltételeként operál, tehát akkor a fő táblából ki fogja hagyni azokat, ahol nincs komment, és nem a kommentek számát mutatja, hanem az összes rekord számát.

SELECT uuid, COUNT(th.task_uuid) AS history_count
FROM tasks t 
LEFT JOIN task_history th 
ON t.uuid=th.task_uuid 
GROUP BY t.uuid
HAVING th.comment IS NOT NULL;
uuid      history_count
--------  -------------
cea2c25f  1            
ecbe2ad3  5            
fae35a3b  4            

A megoldás egy CASE elágazás beépítése a COUNT-ba. Így nem fogja számolni azokat a history rekordokat, ahol nincs komment. 

SELECT uuid, COUNT(CASE WHEN th.comment IS NULL THEN NULL ELSE 1 END) AS comment_count
FROM tasks t 
LEFT JOIN task_history th 
ON t.uuid=th.task_uuid 
GROUP BY t.uuid;
uuid      comment_count
--------  -------------
cea2c25f  1            
a1b50896  0            
c5cb739a  0            
de5860ae  0            
e65cee3f  0            
ecbe2ad3  2            
ecbfdd61  0            
fae35a3b  1            

Simán elképzelhető, hogy van sokkal egyszerűbb, triviális megoldás is, csak kevés vagyok hozzá.

Második érdekesség: az ORDER BY-ban lehet egyedi sorrendet meghatározni egyedi feltételek felsorolásával.

ORDER BY
CASE
    WHEN t.src='nagios' THEN 1 
    WHEN t.src='team' 	THEN 2
    WHEN t.src='client' THEN 3
    ELSE 10
END ASC

Hozzászólások

Ez nem egy sima outer join, amit akarsz? 

Szerkesztve: 2024. 04. 22., h – 21:35

Szerinem case when sem kell.....

SELECT uuid, COUNT(th.comment) AS comment_count
FROM tasks t 
LEFT JOIN task_history th 
ON t.uuid=th.task_uuid 
GROUP BY t.uuid;

 

Csak nem mindegy mit szamolsz: uuid vagy comment

Szerkesztve: 2024. 04. 24., sze – 11:36

COUNT(th.comment)

Ha konkrét mezőt adsz meg, akkor a non-nullable értékeket számolja meg.

Szerk.: ja, látom, pont ezt írták egy kommenttel felettem.