08. januar 2015 - 14:14Der er
8 kommentarer og 1 løsning
Kan ikke tælle rigtigt med COALESCE og CASE
Hvad gør jeg forkert her? Jeg har en database med byrådsmedlemmer. En del har skiftet parti i løbet af valgperioden og jeg vil gerne have en liste, der viser, hvor mange mandater de enkelte partier har lige nu.
Jeg har bl.a. disse kolonner: kb_valg13 = parti, som medlemmerne blev valgt for kb_valg13hop = parti, som nogle medlemmer er skiftet til kb_ud = dato for, hvornår nogle medlemmer er trådt ud af byrådet.
Alle medlemmer af lokale lister skal blot slås sammen til "lokallister".
Problemet er, at jeg ikke kan lave en query, som tæller rigtigt, når der er sket et skifte til/fra en lokalliste. Fx er der pt. i alt 25 løsgængere, men listen viser kun 23. Det passer med de to fra lokallister, som er blevet løsgængere. Jeg har eksperimenteret med at lade et byrådsmedlem skifte fra en lokalliste til Venstre, men dette fanges heller ikke af min query.
Nedenstående er min seneste udgave, men jeg har prøvet alle mulige kombinationsmuligheder. Jeg formoder selv, at det er min CASE, der skaber problemer ...
SELECT CASE WHEN kb_valg13 LIKE '%lokal%' OR kb_valg13 LIKE 'Slesvigsk Parti' OR kb_valg13hop LIKE '%lokal%' OR kb_valg13hop LIKE 'Slesvigsk Parti' THEN '<em>lokallister</em>' WHEN kb_valg13hop LIKE 'UP' THEN '<em>løsgængere</em>' ELSE COALESCE(kb_valg13hop, kb_valg13) END as Parti, COUNT(COALESCE(kb_valg13hop, kb_valg13)) as Antal FROM kb_medlemmer WHERE kb_ud IS NULL GROUP BY Parti ORDER BY Antal DESC
Når jeg fifler med query'en kan jeg se, at du har delvist ret i din formodning.
- Query'en i #1 fanger ikke dem, der har skiftet fra en lokalliste til et andet parti - men kan godt tælle de, der er blevet løsgængere.
- At bytte rundt på de to WHEN giver næsten det samme: Men nu kan den heller ikke tælle dem fra lokallister, der er blevet løsgængere.
- At slette WHEN med UP=løsgænger giver det samme som #1 (UP/løsgænger behandles som et parti hvilket også er forventeligt).
- Hvis jeg sletter begge WHEN og laver en liste med alle partier (inkl. de 50 lokallister), så tæller den helt rigtigt.
Er der nogen idéer til, hvordan jeg ellers kan bygge en query, der både samler alle lokallisterne i én og laver noget a la COALESCE(kb_valg13hop, kb_valg13)?
Jeg tror at vi skal dele det her op i flere mindre delopgaver.
Ja - det kan man godt i SQL.
Det vil tit vaere langsomt, men den her database er jo ikke saa stor og derfor gaar det sikkert.
Foerst checker vi at:
SELECT COALESCE(kb_valg13hop, kb_valg13) AS kb_idag FROM kb_medlemmer WHERE kb_ud IS NULL
returnerer det den skal.
Saa lave vi den lille konvertering af diverse ikke-landsdaekkende partier:
SELECT CASE WHEN kb_idag LIKE '%lokal%' OR kb_idag = 'Slesvigsk Parti' THEN 'lokallister' WHEN kb_idag = 'UP' THEN 'løsgængere' ELSE kb_idag END as kb_idag_justeret FROM ( SELECT COALESCE(kb_valg13hop, kb_valg13) AS kb_idag FROM kb_medlemmer WHERE kb_ud IS NULL ) x
Og ser om det virker.
Og saa taeller vi:
SELECT kb_idag_justeret,COUNT(*) AS antal FROM ( SELECT CASE WHEN kb_idag LIKE '%lokal%' OR kb_idag = 'Slesvigsk Parti' THEN 'lokallister' WHEN kb_idag = 'UP' THEN 'løsgængere' ELSE kb_idag END as kb_idag_justeret FROM ( SELECT COALESCE(kb_valg13hop, kb_valg13) AS kb_idag FROM kb_medlemmer WHERE kb_ud IS NULL ) x ) xx GROUP BY kb_idag_justeret
Mange lange tak, der er point, hvis du lægger et svar.
Tillægsspørgsmål: Hvor kan jeg lægge en kolonne ind, der tæller mandaterne fra de partier, de oprindeligt blev valgt for (kb_valg13 WHERE kb_valgt13 = 1)?
Jeg har forsøgt mig med subqueries og UNION, men der sker ingenting ... (måske fordi nogle byrådsmedlemmer er trådt ud og andre er kommet til?)
SELECT CASE WHEN kb_valg13 LIKE '%lokal%' OR kb_valg13 LIKE 'Slesvigsk Parti' THEN 'lokallister' ELSE kb_valg13 END AS Parti, COUNT(kb_valg13) AS KV13 FROM kb_medlemmer WHERE kb_valgt13 = 1 GROUP BY Parti ORDER BY KV13 DESC
... men jeg gerne have de to resultater som før-og-nu kolonner i samme tabel. Som nævnt har jeg puslet med subquery og union, men kan ikke få det til at virke og har heller ikke kunnet finde det særligt godt beskrevet noget sted.
Men så vidt jeg kan læse mig til, kan det give problemer, hvis der ikke er det samme antal rækker i begge kolonner - og der er jo ingen UP/løsgængere i før-kolonnen.
Nu har jeg endelig haft lejlighed til at afprøve dit forslag - og det virker! (naturligvis)
Mange, mange tak!
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.