虽然我知道标题不是非常具体而且我道歉,但我需要帮助解决SQL语法问题,因为我不完全确定语法部分是错误的,我不能更具体。
我正在使用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行是否带有下划线黄色,并建议将CASE添加到我的分组语句中。我不是SQL上最伟大的,所以如果它显而易见,请毫不犹豫地打电话给我。
答案 0 :(得分: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
分组不起作用,因为您选择的CASE会以不适合GROUP BY的方式转换结果。
我认为您不需要DISTINCT,因为此关键字已应用于选择列表中的所有表达式,并且在您的情况下将其设置为没有意义(因为您已经没有与之相关的&# 39;重新分组)
答案 1 :(得分:0)
有两种方法:
1
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;
INLINE
视图。此处有一个类似的问题How do I use Group By based on a Case statement in Oracle?
答案 2 :(得分:0)
首先,您不需要select distinct
。使用group 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
带来了额外的列,而非行,因此您将拥有“dog”列和“cat”列。这些可以很容易地用在SELECT
的逻辑中。假设某个宠物是狗或猫,但从不两者兼而有之,查询只使用MAX()
而不是在group by
中包含其他列。
从or
条件中删除join
可以提高效果。
如果您正在学习SQL,请学习正确的ANSI样式join
语法。一个简单的规则:永远不要在from
子句中使用逗号。
答案 3 :(得分:0)
另一个答案是乘坐和可读性。从您的宠物开始,通过LEFT-JOIN加入狗或猫桌,只能在其中一张桌子上找到。如果您允许其他宠物入住(鸟类,爬行动物等),您可以在这些表格中添加更多“LEFT JOIN”并调整case / when子句。
所以,案例/何时。如果发现狗的宠物编号匹配,那么你就像“狗”一样。如果没有,它会通过尝试“猫”...如果没有,你有你的其他(或将来的任何其他宠物类型)。
我已经添加了pet_number以进行澄清,这也是你的小组的一部分...如果你有多个名为“闪电”的宠物(快狗或猫,每个都有不同的宠物编号),没有歧义。< / p>
另外,对于小组来说,我是在主宠物的宠物编号栏上做的。如果它在狗或猫表中找到它并不重要......无论在哪个表中找到它,它都是不同的数字。
最后,删除了明显的。由于您按每个宠物编号/名称进行分组,并进行总和,因此根据生成的宠物类型不会有任何重复...
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;
但是,如果Oracle扼杀说不是所有列都是该组聚合的一部分,因为您没有按宠物类型进行分组...并且宠物类型不会因特定宠物编号而改变,您可以只需将其更改为
MAX( case/when ) as PetType
(最后,我讨厌尝试使用嵌入空格的列。可能会导致您可能没有预料到的问题,特别是如果您忘记“引用”它们。)