2015-11-02 33 views
5

To jest to, co mam:Jak dostać wiele SUM() dla różnych kolumn z GROUP BY

SELECT  
    SUBJECT_ID, SUM(SOMETABLE.COLUMN) AS HOURS, POINTS, SEMESTER_ID 
FROM  
    SOME_TABLES 
WHERE  
    (GROUP = (SELECT TOP (1) GROUP 
       FROM SOMETABLE2 
       WHERE (STUDENT_ID = 123))) 
GROUP BY 
    SUBJECT_ID, POINTS, SEMESTER_ID 
HAVING  
    (SUBJECT_ID = 782) 

tego zapytania Powroty:

enter image description here

trzeba uzyskać ten wynik:

enter image description here

aby ta powoduje, że jestem Korzystając z tej strony internetowej:

SELECT  
    SUBJECT_ID, SUM(SOMETABLE.COLUMN) AS HOURS, 
    SUM(SOMETABLE3.COLUMN) AS POINTS, SEMESTER_ID 
FROM 
    SOME_TABLES 
WHERE  
    (GROUP = (SELECT TOP (1) GROUP 
       FROM SOMETABLE2 
       WHERE (STUDENT_ID = 123))) 
GROUP BY 
    SUBJECT_ID, SEMESTER_ID 
HAVING  
    (SUBJECT_ID = 12) 

ale zwraca SUM bez tym GROUP BY oświadczenie - jak na drugim screenie, ale jest dwa razy 16 punktów, natomiast nie powinno być dwa rzędy z 8 punktów w semestrze.

Jak uzyskać prawidłowe PUNKTY do SEMESTER_ID? W komentarzu pod tym postem znajduje się skrypt z przykładowymi danymi .

+2

Podaj nam przykładowe dane do pracy z ... –

+0

Podsumowujecie 'SOMETABLE3.COLUMN', którego nigdzie nie widać w zapytaniu ... –

+0

Dodaj' where points> 0'. Jeśli to nie jest to, czego chcesz, spróbuj wyjaśnić logikę, którą * potrzebujesz * dla zapytania. –

Odpowiedz

0

Można użyć OVER klauzulę, coś jak:

QUERY

select distinct 
     Id, 
     sum(Hours) over (partition by SimId) Hours, 
     sum(Points) over (partition by SimId) Points, 
     SimId 
from #t 

przykładowe dane

create table #t 
(
    Id INT, 
    Hours INT, 
    Points INT, 
    SimId INT 
) 

insert into #t values 
(787,100,0,214858), 
(787,0,8,214858), 
(787,100,8,233562), 
(787,0,0,233562) 

WYJŚCIE

Id Hours Points SimId 
787 100  8  214858 
787 100  8  233562 

UPDATE

To dlatego, że nie dostarczyły danych próbki można zrobić z CTE w następujących:

WITH cte AS 
(
SELECT  
    SUBJECT_ID, SUM(SOMETABLE.COLUMN) AS HOURS, 
    SUM(SOMETABLE3.COLUMN) AS POINTS, SEMESTER_ID 
FROM 
    SOME_TABLES 
WHERE  
    (GROUP = (SELECT TOP (1) GROUP 
       FROM SOMETABLE2 
       WHERE (STUDENT_ID = 123))) 
GROUP BY 
    SUBJECT_ID, SEMESTER_ID 
HAVING  
    (SUBJECT_ID = 12) 
) 
SELECT DISTINCT SUBJECT_ID, 
     sum(Hours) over (partition by SEMESTER_ID) Hours, 
     sum(Points) over (partition by SEMESTER_ID) Points, 
     SEMESTER_ID 
FROM cte 

UPDATE 2

Można tworzyć #temp_table i wstawić dane z Twojego zapytania, po tym, jak użyje się CTE w:

;WITH cte AS 
(
SELECT * 
FROM #temp_table 
) 
SELECT DISTINCT SUBJECT_ID, 
     sum(Hours) over (partition by SEMESTER_ID) Hours, 
     sum(Points) over (partition by SEMESTER_ID) Points, 
     SEMESTER_ID 
FROM cte 
+0

#t jest tabelą tymczasową zdefiniowaną w części "Przykładowe dane" w swojej odpowiedzi. Wygląda na to, że jest wypełniony przykładowymi danymi z postu PO. – BenM

+0

Dzięki, ale gdy próbuję uruchomić to zapytanie, otrzymuję: 'Kolumna 'cte.HOURS' jest niepoprawna na liście wyboru, ponieważ nie jest zawarta ani w funkcji agregującej, ani w klauzuli GROUP BY." Bez grupy przez i otrzymywać wyniki bez błędów. –

+0

@ TABAlleman Widziałeś mój post przed edycją. –

0

Rozważ użycie CROSS APPLY, aby uzyskać sumę dla każdej kolumny.

SELECT  
    SUBJECT_ID, studentHours.hoursWorked AS HOURS, studentPoints.pointsEarned AS POINTS, SEMESTER_ID 
FROM  
    SOME_TABLES 
CROSS APPLY (
    SELECT SUM(someColumn) as hoursWorked 
    FROM SOMETABLE2 
    WHERE STUDENT_ID = 123 
) studentHours 
CROSS APPLY (
    SELECT SUM(someColumn) as pointsEarned 
    FROM SOME_POINTS_TABLE 
    WHERE STUDENT_ID = 123 
) studentPoints 
WHERE SUBJECT_ID = 12 
GROUP BY 
    SUBJECT_ID, SEMESTER_ID 
-1

Nie jestem pewien, czy to bardzo pomoże, ale klauzula TOP zwykle nie wymaga nawiasów. Edycja: Aby uzyskać najlepszą praktykę, klauzula ORDER BY jest zalecana podczas korzystania z klauzuli TOP. Możesz także spróbować ZAMÓWIĆ razem z LIMITEM. To może pomóc.

+1

top (x) jest idealnie poprawne. Potrzebujesz nawiasów, jeśli umieścisz coś innego, jak: górny (@x) lub górny (wybierz maks. (X) z tabeli) –

+0

Huh. Właśnie zauważyłem, że OP nie używa MySQL. Czy nadal potrzebuje nawiasu, ponieważ nie przekazuje wyrażenia? – Mikey

+0

podczas korzystania z numeru, obie działają poprawnie: góra 1 lub góra (1). Ma to na celu kompatybilność wsteczną i należy użyć nawiasów. –

1

Spróbuj to zamiast:

SELECT 
    SUBJECT_ID,SEMESTER)ID 
    ,SUM(HOURS) as HOURS 
    ,SUM(POINTS) as POINTS 
FROM SOME_TABLES 
WHERE SUBJECT_ID = 12 
GROUP BY 
    SUBJECT_ID,SEMESTER)ID 
0

Z sample table kwerendy powinien wyglądać następująco:

WITH cte AS (SELECT SUBJECT_ID, HOURS, POINTS, SEMESTER_ID FROM SAMPLE_TABLE2 GROUP BY HOURS, POINTS, SUBJECT_ID, SEMESTER_ID ) SELECT DISTINCT SUBJECT_ID, sum(Hours) over (partition by SEMESTER_ID, SUBJECT_ID) Hours, sum(Points) over (partition by SEMESTER_ID, SUBJECT_ID) Points, SEMESTER_ID FROM cte

Kluczem było:
sum(Hours)over(partition by SEMESTER_ID,SUBJECT_ID) hours i:
GROUP BY HOURS, POINTS, SUBJECT_ID, SEMESTER_ID wewnątrz INNER QUERY.

Dzięki @Stanislovas Kalašnikovas!