Vi har en liten "aktivitetstävling" på webben mellan våra kontor på jobbet och nu försöker jag få fram vilken aktivitet (fotboll, styrketräning etc) som har fått flest minuter registrerade av de anställda för respektive kontor (alltså vilka aktiviteter som utövats mest under en given period).
DB består av 3 tabeller:
Tabell 1: Health
HealthID(pk) EmployeeID HealthDate Office
Jag behöver alltså på något sätt summera ihop antal minuter för varje akvititet på respektive kontor och plocka ut den aktivitet som har flest antal minuter. För varje rad i tabellen Health kan alltså HealthActivity innehålla en eller flera aktiviteter.
Jag har inte kommit så långt men en liten bit:
SELECT DISTINCT Health.Office, SUM(HealthActivity.Minutes) AS SumMinutes
FROM Health
INNER JOIN HealthActivity ON Health.HealthID = HealthActivity.HealthID
GROUP BY Health.Office
Här får jag alltså fram antal aktivitetsminuter totalt för respektive kontor, men jag vill alltså även för respektive kontor få fram vilken aktivitet som har flest av dessa minuter. Någon som har en smart lösning?
SELECT activityName,
Health.Office,
SUM(HealthActivity.Minutes) AS SumMinutes
FROM Health INNER JOIN HealthActivity
ON Health.HealthID = HealthActivity.HealthID
inner join ActivityTypes
on ActivityTypes.activitytype = healthactivity.activitytype
GROUP BY Health.Office , activityName
order by SumMinutes Desc
Ett litet prob bara, den plockar ut alla aktiviteter för respektive kontor (vilket även innebär att varje kontor listas flera gånger)... vill bara ta ut EN aktivitet för varje kontor, den aktivitet som har flest antal minuter registrerade.... och varje kontor ska bara listas en gång. Försökte sätta distinct men det funkade inte...
SELECT activityName,
Health.Office,
SUM(HealthActivity.Minutes) AS SumMinutes
FROM Health as H INNER JOIN HealthActivity
ON Health.HealthID = HealthActivity.HealthID
inner join ActivityTypes
on ActivityTypes.activitytype = healthactivity.activitytype
GROUP BY Health.Office , activityName
having sum(HealthActivity.Minutes) = (
select max(sumMinutes) from (SELECT SUM(HealthActivity.Minutes) AS SumMinutes
FROM Health INNER JOIN HealthActivity
ON Health.HealthID = HealthActivity.HealthID
where health.office = h.office) s
GROUP BY activityId )
Får ett felmeddelande: "Column 'HealthActivity.ActivityID' is invalid in the HAVING clause because it is not contained in either an aggregate funktion or the GROUP BY clause."
SELECT activityName,
H.Office,
SUM(HealthActivity.Minutes) AS SumMinutes
FROM Health as H INNER JOIN HealthActivity
ON H.HealthID = HealthActivity.HealthID
inner join ActivityTypes
on ActivityTypes.activitytype = healthactivity.activitytype
GROUP BY H.Office , activityName
having sum(HealthActivity.Minutes) = (
select max(sumMinutes) from
(SELECT SUM(HealthActivity.Minutes) AS SumMinutes
FROM Health INNER JOIN HealthActivity
ON Health.HealthID = HealthActivity.HealthID
where health.office = h.office
GROUP BY activityId ) s)
Hm, det fungerade visst inte ändå. Jag testade bara lite snabbt direkt i ms sql-server med ett par inskrivna värden. Men när jag stoppade in sql-frågan i den riktiga applikationen så resultatet rätt mystiskt. Den plockar fram tre kontor var av två är samma och minuterna är också fel.
Det verkar som den ballar ur när man har fler än 4-5 olika rader i tabellen Health??? Behöver nog lite hjälp igen...
Nu vet jag när det blir fel... men inte hur man löser det tyvärr. Jag bifogar även en bild på mina tabeller som förklarar hur felet uppstår.
Som jag skrev förut så innehåller varje Health en eller flera HealthActivity. En health kan också innehålla flera olika HealthActivity med _samma_ ActivityType.
Ett exempel: Jag spelar fotboll på förmiddagen och sedan spelar jag fotboll på eftermiddagen samma dag. Dessa skriver jag in som två separata HealthActivity (men kopplade till samma rad i Health). Det är alltså när jag skriver samma typ av aktivitet i två eller fler HealthActivity för samma HealthID som det blir fel.
Jag bumpar upp den här frågan då den blivit aktuell för min del igen. Tabellerna är samma men jag tänkte göra det lite lättare för mig (men lyckades ändå inte :) )
Jag plockar nu bara ut aktivitetsnamnet och det totala antalet minuter som finns registrerat för aktiviteten under en period. Jag vill dock även få ut antal minuter för respektive kontor i samma sql-sats, så här: