Toon posts:

[SQL] Group by op subquery in SELECT

Pagina: 1
Acties:
  • 509 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik ben bezig met een SQL opdracht en ik loop nu vast op het volgende.

Ik heb de volgende query:

Afbeeldingslocatie: http://img65.imageshack.us/img65/1056/sql2ww.th.jpg

Iedere row is een telefoongesprek tussen twee klanten. Van beide klanten heb ik het inkomen getoond.
Het is uiteindelijk de bedoeling dat ik het volgende kan tonen:

Per maand de totale gesprekstijd tussen inkomensgroepen.

Ik loop nu vast op het volgende:
  1. Hoe kan ik een Sum() gebruiken op Gespreksduur,
  2. En hoe kan ik vervolgens de inkomens verdelen in groepen? (Bijv. laag/gemiddeld/hoog ipv huidige inkomens.)
Want als ik de Sum() functie gebruik dan zal ik een group by moeten gebruiken, maar dat krijg ik niet voor elkaar vanwege de subquery in de SELECT.

Het tweede punt zou kunnen met een CASE o.i.d., maar daar kom ik niet uit.

Ik werk in SQL server zoals jullie kunnen zien. Ik ben totaal geen programmeur, mss dat ik nu dan ook wel veel te ingewikkeld denk, een beetje hulp zou ik wel kunnen gebruiken. |:(

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 23-12-2025

_Thanatos_

Ja, en kaal

Als je deze hele query nou in een "SELECT * FROM (" ... ") AS calls" wrapt, kun je em veel makkelijker manipuleren, omdat je dan aan het selecteren bent uit een (derived) table zonder subselects. Dan kun je een GROUP BY uitvoeren met een SUM.

Of je maakt er een view van, als je deze informatie vaker nodig hebt ;)

btw, zou je volgende keer je query in [code=sql]...[/code] kunnen plaatsen? Dat leest wat makkelijker...

[ Voor 55% gewijzigd door _Thanatos_ op 05-05-2006 13:36 ]

日本!🎌


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Zou je de tabelstructuur even kunnen posten?

Oops! Google Chrome could not find www.rijks%20museum.nl


  • ZeroCode
  • Registratie: Februari 2002
  • Laatst online: 07-01 13:42

ZeroCode

Woopie

_Thanatos_ schreef op vrijdag 05 mei 2006 @ 13:31:
Als je deze hele query nou in een "SELECT * FROM (" ... ") AS calls" wrapt, kun je em veel makkelijker manipuleren, omdat je dan aan het selecteren bent uit een (derived) table zonder subselects. Dan kun je een GROUP BY uitvoeren met een SUM.

Of je maakt er een view van, als je deze informatie vaker nodig hebt ;)

btw, zou je volgende keer je query in [code=sql]...[/code] kunnen plaatsen? Dat leest wat makkelijker...
Precies alles wrappen in wat hierboven staat, dan kun je altijd nog je group by doen :) Werkt prima!

Verwijderd

Topicstarter
Ah bedankt, ik ben nu al verder op de goede weg. Ik heb nu dit:

SQL:
1
2
3
4
5
6
7
8
SELECT Maand, Sum(Gespreksduur), Ink_beller, Ink_gebelde FROM (
SELECT  D.month AS Maand, C.duration AS Gespreksduur,
    (SELECT Cus.income FROM Customer AS Cus WHERE Cus.customer_no = B.customer) AS Ink_beller,  
    (SELECT Cus.income FROM Customer AS Cus WHERE Cus.customer_no = C.called_customer) AS Ink_gebelde
FROM Call AS C, Bill AS B, [Day] AS D
WHERE C.bill = B.bill_no
AND C.date = D.date) AS Calls
GROUP BY Maand, Ink_beller, Ink_gebelde


Enige dat ik nu nog moet realiseren is het hernoemen van de inkomens naar groepen, dus laag/gem/hoog. Welke functie kan ik daarvoor gebruiken?

Ik heb ook de database structuur ff meegepost mocht dat handig zijn.

Afbeeldingslocatie: http://img51.imageshack.us/img51/3225/dbstructuur0nf.th.jpg

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Ik zou de inkomens in een aparte tabel zetten

InkomensGroep, MinumumInkomen, MaximumInkomen

en dan joinnen met die tabel

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Ecto2002
  • Registratie: Juni 2002
  • Laatst online: 05-09-2025
Dit kan je eventueel met een geneste CASE WHEN .... ELSE .... END statement doen.

CASE WHEN Inkomen > 500 THEN (CASE WHEN Inkomen < 6000 THEN 'Gemiddeld' ELSE 'Hoog' END) ELSE 'Laag' END)

Misschien zijn er nog andere oplossingen natuurlijk

Verwijderd

Topicstarter
Dat zou ik zelf ook gedaan hebben, probleem is alleen dat ik de structuur niet mag wijzigen. Excuses, was ik vergeten te vermelden. Wel goed idee idd.

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Ok, dan moet je het met case doen

CASE
WHEN inkomen BETWEEN 0 AND 1000 THEN 'Veel te weinig'
WHEN inkomen BETWEEN 1000 AND 2000 THEN 'Al iets meer'
....
END

Oops! Google Chrome could not find www.rijks%20museum.nl


Verwijderd

Topicstarter
Ben al een heel eind nu:

SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SELECT Maand, Sum(Gespreksduur) AS Minuten, 

(CASE
WHEN Ink_gebelde BETWEEN 0 AND 35000 THEN 'Laag'
WHEN Ink_gebelde BETWEEN 35000 AND 60000 THEN 'Gemiddeld'
WHEN Ink_gebelde > 60000 THEN 'Hoog'
ELSE 'Onbekend'
END) AS Ink_gebelde,

(CASE
WHEN Ink_beller BETWEEN 0 AND 35000 THEN 'Laag'
WHEN Ink_beller BETWEEN 35000 AND 60000 THEN 'Gemiddeld'
WHEN Ink_beller > 60000 THEN 'Hoog'
ELSE 'Onbekend'
END) AS Ink_beller

FROM (

SELECT  D.month AS Maand, C.duration AS Gespreksduur,
    (SELECT Cus.income FROM Customer AS Cus WHERE Cus.customer_no = B.customer) AS Ink_beller,  
    (SELECT Cus.income FROM Customer AS Cus WHERE Cus.customer_no = C.called_customer) AS Ink_gebelde

FROM Call AS C, Bill AS B, [Day] AS D

WHERE C.bill = B.bill_no
AND C.date = D.date) AS Calls

GROUP BY Maand, Ink_beller, Ink_gebelde


Enige wat er nu niet klopt is dat de GROUP BY niet het juiste pakt.

Afbeeldingslocatie: http://img62.imageshack.us/img62/4120/sql25vq.th.jpg

Er wordt bijvoorbeeld in de eerste maand in de db vaker calls weergegeven tussen categorie hoog en gemiddeld. Die zouden ook samen genomen moeten worden.

Per maand zou er moeten staan:

Laag Laag Minuten
Laag Gem Minuten
Laag Hoog Minuten
Gem Laag Minuten
Gem Gem Minuten
etc..

[edit]

Ik heb ook hier weer een SELECT * FROM omheen gezet en daar een group by op los gelaten. Nu heb ik het gewenste resultaat :)

Bedankt allemaal voor jullie hulp _/-\o_

[ Voor 19% gewijzigd door Verwijderd op 05-05-2006 15:43 ]

Pagina: 1