/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
SELECT i MySQL 3.23.52
Fra : Jesper Frank Nemholt


Dato : 24-01-03 23:07

Hej!

Lige en SQL jeg ikke lige kan greje.
Jeg har følgende table (ligegyldige felter udeladt) :

mysql> desc process;
+----------------+-----------------------+------+-----+---------------------
+-------+
| Field | Type | Null | Key | Default
| Extra |
+----------------+-----------------------+------+-----+---------------------
+-------+
| timecode | datetime | | | 0000-00-00 00:00:00
| |
| systemid | smallint(5) unsigned | | MUL | 0
| |
| username | varchar(20) | | |
| |
| cpuusage | float(4,2) | YES | | NULL
| |
+----------------+-----------------------+------+-----+---------------------
+-------+

Jeg har en select der finder de 5 brugere der bruger mest CPU :

SELECT username, sum(cpuusage) AS sum_cpuusage FROM process WHERE systemid =
'2' AND timecode > now() - INTERVAL 1 DAY GROUP BY username ORDER BY
sum_cpuusage DESC LIMIT 5

Herefter vil jeg så gerne lave en select der for hver af disse brugere
lister deres CPU forbrug over tid. Dette bruger jeg så senere til at lave
grafer med.
For hvert timestamp kan samme bruger godt gå igen flere gange, da der
registeres per proces-basis, det er derfor jeg benytter mig af sum() og
group by.

Hvis jeg f.eks. siger at de 2 brugere der bruger mest CPU er bruger1 og
bruger2, så ville hver individuel select se således ud :

SELECT timecode,
sum(cpuusage) AS bruger1
FROM process
WHERE systemid = '2'
AND username = 'bruger1'
AND timecode > now() - INTERVAL 1 DAY
GROUP BY timecode
ORDER BY timecode

SELECT timecode,
sum(cpuusage) AS bruger2
FROM process
WHERE systemid = '2'
AND username = 'bruger2'
AND timecode > now() - INTERVAL 1 DAY
GROUP BY timecode
ORDER BY timecode

Nu ville jeg gerne have dem kombineret i een select så det kommer ud i
formatet "timecode, bruger1, bruger2".

Hvordan gøres dette ???

Jeg havde tænkt noget i stil med :

SELECT bruger1.timecode,
sum(bruger1.cpuusage) AS bruger1,
sum(bruger2.cpuusage) AS bruger2
FROM process AS bruger1,
process AS bruger2
WHERE bruger1.systemid = '2'
AND bruger1.username = 'bruger1'
AND bruger1.timecode > now() - INTERVAL 1 DAY
AND bruger2.systemid = '2'
AND bruger2.username = 'bruger2'
AND bruger2.timecode > now() - INTERVAL 1 DAY
GROUP BY bruger1.timecode
ORDER BY bruger1.timecode


Problemet er at det ikke giver de rette værdier, så et eller andet går galt.
Jeg formoder at det er min group by eller noget andet i den stil der er
forkert, men jeg ved ikke lige hvad.

Nogen der kan hjælpe ?

/Jesper



 
 
Jesper Frank Nemholt (25-01-2003)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 25-01-03 18:53

"Jesper Frank Nemholt" <jfn@dassic.com> wrote in message
news:b0sdg3$2r9$1@sunsite.dk...
> Hej!
>
[clip]

Jeg svarer lige halvvejs på mit eget spørgsmål da jeg er kommet lidt videre.
Ønsket var at få nedenstående 2 selects samlet i een :

>
> SELECT timecode,
> sum(cpuusage) AS bruger1
> FROM process
> WHERE systemid = '2'
> AND username = 'bruger1'
> AND timecode > now() - INTERVAL 1 DAY
> GROUP BY timecode
> ORDER BY timecode
>
> SELECT timecode,
> sum(cpuusage) AS bruger2
> FROM process
> WHERE systemid = '2'
> AND username = 'bruger2'
> AND timecode > now() - INTERVAL 1 DAY
> GROUP BY timecode
> ORDER BY timecode
>
> Nu ville jeg gerne have dem kombineret i een select så det kommer ud i
> formatet "timecode, bruger1, bruger2".

Jeg formoder at det kan gøres v.h.a. en eller anden join, men hvordan ?

I en anden tabel gør jeg følgende (inner join) :

SELECT d1.timecode,
d1.readkb+d1.writekb AS dsk0,
d2.readkb+d2.writekb AS dsk1
FROM disk AS d1
INNER JOIN disk AS d2
ON d1.systemid = '2'
AND d1.name = 'dsk0'
AND d1.timecode > now() - INTERVAL 1 DAY
AND d2.systemid = '2'
AND d2.name = 'dsk1'
AND d2.timecode = d1.timecode
ORDER BY d1.timecode


Dette giver hvad jeg ønsker for disk devices, men så snart jeg laver dette i
forbindelse med sum() går det galt, d.v.s. der skal laves noget om for at
det virker med sum(cpuusage).

/Jesper



Jesper Axelsen (27-01-2003)
Kommentar
Fra : Jesper Axelsen


Dato : 27-01-03 19:30

Hej Jesper

Jeg forstår godt dit problem, men kan ikke lige komme på en måde
hvorpå du kan returnere det ønskede recordset.. Følgende sql kune dog
måske være en alternativ løsning. Som jeg kan se returnerer den de
samme data som dem du ønsker, bare på et andet format.

SELECT username, timecode,
sum(cpuusage) AS totalUsage
FROM process
WHERE systemid = 2
AND username in ( 'bruger1', 'bruger2' )
AND timecode > now() - INTERVAL 1 DAY
GROUP BY username, timecode
ORDER BY username, timecode

Håber det kan hjælpe - om ikke andet så måske give inspiration til din
videre søgen.

Mvh
Jesper


On Sat, 25 Jan 2003 18:52:33 +0100, "Jesper Frank Nemholt"
<jfn@dassic.com> wrote:

>"Jesper Frank Nemholt" <jfn@dassic.com> wrote in message
>news:b0sdg3$2r9$1@sunsite.dk...
>> Hej!
>>
>[clip]
>
>Jeg svarer lige halvvejs på mit eget spørgsmål da jeg er kommet lidt videre.
>Ønsket var at få nedenstående 2 selects samlet i een :
>
>>
>> SELECT timecode,
>> sum(cpuusage) AS bruger1
>> FROM process
>> WHERE systemid = '2'
>> AND username = 'bruger1'
>> AND timecode > now() - INTERVAL 1 DAY
>> GROUP BY timecode
>> ORDER BY timecode
>>
>> SELECT timecode,
>> sum(cpuusage) AS bruger2
>> FROM process
>> WHERE systemid = '2'
>> AND username = 'bruger2'
>> AND timecode > now() - INTERVAL 1 DAY
>> GROUP BY timecode
>> ORDER BY timecode
>>
>> Nu ville jeg gerne have dem kombineret i een select så det kommer ud i
>> formatet "timecode, bruger1, bruger2".
>
>Jeg formoder at det kan gøres v.h.a. en eller anden join, men hvordan ?
>
>I en anden tabel gør jeg følgende (inner join) :
>
>SELECT d1.timecode,
>d1.readkb+d1.writekb AS dsk0,
>d2.readkb+d2.writekb AS dsk1
>FROM disk AS d1
>INNER JOIN disk AS d2
>ON d1.systemid = '2'
>AND d1.name = 'dsk0'
>AND d1.timecode > now() - INTERVAL 1 DAY
>AND d2.systemid = '2'
>AND d2.name = 'dsk1'
>AND d2.timecode = d1.timecode
>ORDER BY d1.timecode
>
>
>Dette giver hvad jeg ønsker for disk devices, men så snart jeg laver dette i
>forbindelse med sum() går det galt, d.v.s. der skal laves noget om for at
>det virker med sum(cpuusage).
>
>/Jesper
>


Jesper Frank Nemholt (27-01-2003)
Kommentar
Fra : Jesper Frank Nemholt


Dato : 27-01-03 20:46

"Jesper Axelsen" <jesper@xelsen.dk> wrote in message
news:3mua3v4t2radcs52c6lbae1qgfisvje9ok@4ax.com...
> Hej Jesper
>
> Jeg forstår godt dit problem, men kan ikke lige komme på en måde
> hvorpå du kan returnere det ønskede recordset.. Følgende sql kune dog
> måske være en alternativ løsning. Som jeg kan se returnerer den de
> samme data som dem du ønsker, bare på et andet format.
>
> SELECT username, timecode,
> sum(cpuusage) AS totalUsage
> FROM process
> WHERE systemid = 2
> AND username in ( 'bruger1', 'bruger2' )
> AND timecode > now() - INTERVAL 1 DAY
> GROUP BY username, timecode
> ORDER BY username, timecode
>
> Håber det kan hjælpe - om ikke andet så måske give inspiration til din
> videre søgen.

Der var en på MySQL listen der rystede den rette SQL ud af ærmet. Det er i
samme stil som din, men med nogle IF statements tilføjet.
Jeg har testet den og den funger og er nu implementeret i PHP så den retter
brugernavnene til dynamisk :

SELECT timecode,
SUM(IF(username='bruger1',cpuusage,0)),
SUM(IF(username='bruger2',cpuusage,0))
FROM process
WHERE systemid = '2' AND
timecode > now() - INTERVAL 1 DAY AND
username in ('bruger1', 'bruger2')
GROUP BY timecode
ORDER BY timecode
Det fungerer i pricippet a la den left outer join jeg bruger til disk
statistics ved, korrekt til mit brug, at putte 0 ind de steder hvor der er
en timecode men hvor en bruger ikke har registeret CPU forbrug. Dette gør at
graferne ser korrekte ud.

Jeg ved ikke om jeg reelt også kunne bruge en left outer join, men de spæde
forsøg jeg gjorde gav ikke det rette sammen med sum().

/Jesper



Søg
Reklame
Statistik
Spørgsmål : 177552
Tips : 31968
Nyheder : 719565
Indlæg : 6408849
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste