2016-07-12 45 views
0

我有一個表格,其中包含以下列,我試圖創建一個視圖以創建報告,我需要獲取特定類的完成小時數的總和,但與一個特定的過濾器:通過過濾器獲得總計,多個分組

| PK_CLASS_DAYS_ID | FK_MAIN_ID | FK_CLASS_ID | CLASS_DAY | OUTCOME | CLASS_DATE | HOURS | 
|------------------|------------|-------------|-----------|---------|------------|-------| 
| 1    | 27452  | 137   | 1   | *15  | 2015-11-15 | 8  | 
| 2    | 27452  | 137   | 2   | *15  | 2015-11-16 | 8  | 
| 3    | 27452  | 137   | 4   | *15  | 2015-11-18 | 8  | 
| 4    | 27452  | 137   | 5   | BS15 | 2015-11-19 | 8  | 
| 5    | 27452  | 2   | 1   | *16  | 2001-01-01 | 8  | 
| 6    | 27452  | 48   | 1   | *16  | 2016-01-12 | 8  | 
| 7    | 27452  | 48   | 2   | *16  | 2016-02-27 | 4  | 
| 8    | 27452  | 2   | 1   | *17  | 2017-07-01 | 8  | 
| 9    | 27452  | 137   | 1   | *16  | 2016-07-16 | 8  | 

我需要找到的完成了每一個類(FK_CLASS_ID)爲每一個學生在我的表時間的總和(目前我把它過濾ID 27452出於測試目的),同時,應用以下濾波器(FK_CLASS_ID):

  • (1)CLASS_DAY必須是不同的
  • (2)CLASS_OUTCOME必須以 「*」
  • (3)CLASS_DATE必須是最新的,同時仍然具有先前的兩個條件開始。結果視圖應該如下:
| PK_CLASS_DAYS_ID | FK_MAIN_ID | FK_CLASS_ID | Hrs | 
|------------------|-------------|--------------|------| 
| 1    | 27452  | 137   | 32 | 
| 2    | 27452  | 2   | 8 | 
| 3    | 27452  | 48   | 12 | 

我已經試圖做到這一點得到了最遠的,是下面的select語句:

SELECT 
t1.CLASS, 
SUM(class_hours) as Hrs, 
GROUP_CONCAT('D',classes_days.class_day) as DaysList, 
main.FULLNAME 
FROM 
classes t1 
INNER JOIN classes_days ON classes_days.FK_CLASS_ID = t1.CLASS_ID 
INNER JOIN main ON main.PK_MAIN_ID = classes_days.FK_MAIN_ID 
WHERE 
main.PK_MAIN_ID = 27452 
GROUP BY FK_CLASS_ID 
ORDER BY CLASS 
+0

你能解釋你有什麼問題嗎? – Mureinik

+1

標記時應該小心。 sql server <> mysql。我會編輯標籤,但現在有一個掛起的編輯。 –

+0

我的當前語句不考慮不同的CLASS_DAY列,也不會只添加最近的日期,如果對於相同的FK_CLASS_ID有兩行具有相同的CLASS_DAY。此外,它只能添加具有以星號開頭的列OUTCOME的行。這是針對MySQL v5.6的。 – Gustavo1478

回答

0

對於你想要什麼要完成,您需要使用所需的求和查詢過濾連接,並根據檢索到的記錄集提供所需條件的連接。

立足其關閉您所提供的查詢和期望的結果,它應該看起來像:

SELECT 
`t1`.`CLASS`, 
SUM(`class_hours`.`HOURS`) AS `Hrs`, 
GROUP_CONCAT('D', `class_hours`.`CLASS_DAY` ORDER BY `class_hours`.`CLASS_DAY`) AS `DaysList`, 
`main`.`FULLNAME` 
FROM `classes` AS `t1` 
INNER JOIN (
    #Filter the total hours by student, class, and day 
    SELECT `class_dates`.`FK_MAIN_ID`, `class_dates`.`CLASS_DAY`, `class_dates`.`FK_CLASS_ID`, SUM(`class_dates`.`HOURS`) as `HOURS` 
    FROM (
     #Filter Most Recent Days beginning with star, by most recent date 
     SELECT `classes_days`.* 
     FROM `classes_days` 
     WHERE `classes_days`.`OUTCOME` LIKE '*%' 
     ORDER BY `CLASS_DATE` DESC 
    ) AS `class_dates` 
    GROUP BY `class_dates`.`FK_MAIN_ID`, `class_dates`.`CLASS_DAY`, `class_dates`.`FK_CLASS_ID` 
) AS `class_hours` 
ON `class_hours`.`FK_CLASS_ID` = `t1`.`CLASS_ID` 
INNER JOIN `main` 
ON `main`.`PK_MAIN_ID` = `class_hours`.`FK_MAIN_ID` 
GROUP BY `class_hours`.`FK_MAIN_ID`, `class_hours`.`FK_CLASS_ID` 
ORDER BY `FULLNAME`, `CLASS`; 

導致:

| CLASS | Hrs | DaysList | FULLNAME | 
|---------|-----|-------------|----------| 
| History | 8 |   D1 |  Joe | 
| Math | 32 | D1,D2,D4 |  Joe | 
| Science | 12 |  D1,D2 |  Joe | 
| Math | 10 |  D1,D2 |  Mike | 

例:表http://sqlfiddle.com/#!9/d5828/1

原始查詢是最重要的查詢。子查詢連接示例是底部查詢結果。刪除了PK_MAIN_ID標準,以顯示其對多個條目

工作的時候要記住,MySQL的GROUP BY + ORDER BY並不總能取得預期的效果,並應該使用子查詢,這是證明在連接子查詢,以便進行過濾獲取以*開頭的最新日期。

+0

哇!該聲明看起來很有用,它需要我花一些時間來閱讀和理解它。一旦我做了,我會將其應用於我的情況並報告結果。感謝您的回覆,非常感謝。 – Gustavo1478

+0

我調整了您的原始聲明以獲得我想要的結果,而不是選擇#Filter最近幾天以星號開頭,最近日期部分中的所有記錄。而不是選擇所有我選擇的特定列並使用DISTINCT。按預期工作,謝謝。儘管我覺得我將不得不將這個陳述分解成不同的觀點,以便它能夠按照我的需要進行工作。 – Gustavo1478

+0

我不禁注意到,聲明中的所有字段都有單引號,是否有原因?這有什麼不同嗎? – Gustavo1478