2014-12-06 65 views
0

雖然我知道標題並不是非常具體,但我很抱歉,我需要幫助解決與SQL有關的語法問題,因爲我不完全確定部分語法錯誤,我不能更具體。SQL語法問題 - Group By - Oracle

我正在使用Oracle SQL Developer,如果有幫助的話。

SELECT DISTINCT pet.PET_NAME, 
    CASE 
     WHEN dog.PET_PET_NUMBER = pet.PET_NUMBER THEN 'Dog' 
     WHEN cat.PET_PET_NUMBER = pet.PET_NUMBER THEN 'Cat' 
     ELSE '' 
    END AS "Pet Type", 
    SUM(res.RESERVATION_START_DATE - res.RESERVATION_END_DATE) AS "Days Stayed" 
    FROM HVK_PET pet, HVK_DOG dog, HVK_CAT cat, HVK_RESERVATION res, HVK_PET_RESERVATION petRes 
    WHERE (pet.PET_NUMBER = dog.PET_PET_NUMBER 
    OR pet.PET_NUMBER = cat.PET_PET_NUMBER) 
    AND res.RESERVATION_NUMBER = petRes.RES_RESERVATION_NUMBER 
    AND petRes.PET_PET_NUMBER = pet.PET_NUMBER 
    GROUP BY pet.PET_NAME, dog.pet_pet_number, cat.pet_pet_number; 

是我的完整代碼,前7行強調黃色與建議通過語句添加情況下,我的團隊。我不是SQL最偉大的人,所以如果明顯的話,不要猶豫,給我打電話吧。

回答

0
SELECT pet.PET_NAME, 
     CASE 
      WHEN dog.PET_PET_NUMBER = pet.PET_NUMBER THEN 'Dog' 
      WHEN cat.PET_PET_NUMBER = pet.PET_NUMBER THEN 'Cat' 
      ELSE '' 
     END AS "Pet Type", 
     SUM(res.RESERVATION_START_DATE - res.RESERVATION_END_DATE) AS "Days Stayed" 
    FROM HVK_PET pet, HVK_DOG dog, HVK_CAT cat, HVK_RESERVATION res, HVK_PET_RESERVATION petRes 
    WHERE (pet.PET_NUMBER = dog.PET_PET_NUMBER OR pet.PET_NUMBER = cat.PET_PET_NUMBER) 
     AND res.RESERVATION_NUMBER = petRes.RES_RESERVATION_NUMBER 
     AND petRes.PET_PET_NUMBER = pet.PET_NUMBER 
    GROUP BY pet.PET_NAME, 
      CASE 
       WHEN dog.PET_PET_NUMBER = pet.PET_NUMBER THEN 'Dog' 
       WHEN cat.PET_PET_NUMBER = pet.PET_NUMBER THEN 'Cat' 
       ELSE '' 
      END; 

分組由dog.pet_pet_number, cat.pet_pet_number不起作用,因爲你在選擇案例轉換成在這樣一種方式,它不適合GROUP BY的結果。

我想你不需要DISTINCT,因爲這個關鍵字被應用到選擇列表中的所有表達式,並且在你的情況下沒有意義(你已經沒有分組了)

0

第一個類似的問題,你不需要select distinctgroup by幾乎不需要這個構造。

您的case聲明存在的問題是,它提到了三列,但只有兩列在group by中。這個缺失的列是pet.PET_NUMBER。您可以將其添加到group by,但有更簡單的方法來編寫您的查詢。

,關鍵是要解決join語法,而不是使用隱式連接:

SELECT pet.PET_NAME, 
     MAX(CASE WHEN dog.PET_PET_NUMBER IS NOT NULL THEN 'Dog' ELSE 'CAT' END) AS "Pet Type", 
     SUM(res.RESERVATION_START_DATE - res.RESERVATION_END_DATE) AS "Days Stayed" 
FROM HVK_PET pet JOIN 
    HVK_PET_RESERVATION petRes 
    ON petRes.PET_PET_NUMBER = pet.PET_NUMBER JOIN 
    HVK_RESERVATION res 
    ON res.RESERVATION_NUMBER = petRes.RES_RESERVATION_NUMBER LEFT JOIN 
    HVK_DOG dog 
    ON pet.PET_NUMBER = dog.PET_PET_NUMBER LEFT JOIN 
    HVK_CAT cat 
    ON pet.PET_NUMBER = cat.PET_PET_NUMBER 
GROUP BY pet.PET_PET_NUMBER, pet.PET_NAME; 

left join小號帶來額外,不所以你有「狗」列和「貓「欄目。這些可以很容易地用於SELECT中的邏輯。假設給定的寵物不是狗或貓,而是兩者都不是,則查詢僅使用MAX()而不是在group by中包括額外的列。

join條件中刪除or應該會提高性能。

如果您正在學習SQL,請學習適當的ANSI風格join語法。一個簡單的規則:從不在from子句中使用逗號。

0

只是另一個答案,爲乘坐和可讀性。從您的寵物開始,通過LEFT-JOIN加入狗或貓桌,只能在其中一張桌上找到。如果您有其他寵物可以逗留(鳥類,爬行動物等),您可以在這些表格上添加更多「左連接點」,並調整案件/何時條款。

那麼,案件/何時。如果如果找到一隻狗的寵物號碼匹配,那麼你做的就是「狗」。如果沒有,它會通過嘗試「貓」...如果沒有,你有其他人(或未來的任何其他類型的寵物)。

我已經添加了pet_number澄清,這也是你的組的一部分......如果你有多個寵物命名爲「閃電」(快狗或貓,每個都有不同的寵物號碼),沒有歧義。

另外,對於羣組,我在主寵物的寵物號碼列上進行操作。不管它是否在狗或貓表中找到它,它都是不同的數字,不管它在哪個表中找到。

最後,刪除了不同的。既然你是通過每個寵物號碼/名稱分組,並做一個總金額,就不會有基於得到的寵物型任何重複...

SELECT 
     pet.PET_NAME, 
     pet.PET_NUMBER, 
     CASE WHEN dog.PET_PET_NUMBER IS NOT NULL THEN 'Dog' 
      WHEN cat.PET_PET_NUMBER IS NOT NULL THEN 'Cat' 
      ELSE '' END AS "Pet Type", 
     SUM(res.RESERVATION_START_DATE - res.RESERVATION_END_DATE) AS "Days Stayed" 
    FROM 
     HVK_PET pet 
     LEFT JOIN HVK_DOG dog 
      ON pet.PET_NUMBER = dog.PET_PET_NUMBER 
     LEFT JOIN HVK_CAT cat 
      ON pet.PET_NUMBER = cat.PET_PET_NUMBER 
     JOIN HVK_PET_RESERVATION petRes 
      ON pet.PET_NUMBER = petRes.PET_PET_NUMBER 
      JOIN HVK_RESERVATION res 
       ON petRes.RES_RESERVATION_NUMBER = res.RESERVATION_NUMBER 
    GROUP BY 
     pet.PET_NAME, 
     pet.PET_NUMBER; 

然而,如果甲骨文扼流圈說,並非所有列是該組的,因爲你沒有被寵物類型分組集合的一部分......和寵物類型不會對特定的寵物數量的改變,你可以改變一個

MAX(case/when) as PetType 

(最後,我討厭嘗試使用嵌入空格的列,可能會導致您可能不期望的問題,特別是如果您忘記「引用」它們。)