我有一个SQL问题,其中代码无法统计不同的ID。它确实计算了它们,但并没有明确地这样做。我在下面提供了一小段代码并加粗了问题。
SELECT
"RESERVATION_STAT_DAILY"."RESORT" AS "RESORT",
"RESERVATION_STAT_DAILY"."BUSINESS_DATE" AS "BUSINESS_DATE",
to_char("RESERVATION_STAT_DAILY"."BUSINESS_DATE",'MON-yyyy') AS "MONTHYEAR",
Extract(day from "RESERVATION_STAT_DAILY"."BUSINESS_DATE") AS "DAY",
Extract(month from "RESERVATION_STAT_DAILY"."BUSINESS_DATE") AS "MONTH",
Extract(year from "RESERVATION_STAT_DAILY"."BUSINESS_DATE") AS "YEAR",
"RESERVATION_STAT_DAILY"."SOURCE_CODE" AS "SOURCE_CODE",
"RESERVATION_STAT_DAILY"."MARKET_CODE" AS "MARKET_CODE",
"RESERVATION_STAT_DAILY"."RATE_CODE" AS "RATE_CODE",
"RESERVATION_STAT_DAILY"."RESV_NAME_ID" AS "RESV_NAME_ID",
(CASE WHEN "RESERVATION_STAT_DAILY"."SOURCE_CODE" = 'GDS'
AND "RESERVATION_STAT_DAILY"."RATE_CODE" NOT IN ('BKIT', 'EXPEDIA')
AND "RESERVATION_STAT_DAILY"."MARKET_CODE" NOT IN ('GOVG', 'ENT')
THEN 'GDS'
ELSE 'Other'
END) AS "BizUnit",
COUNT(DISTINCT CASE WHEN "RESERVATION_STAT_DAILY"."SOURCE_CODE" = 'GDS'
AND "RESERVATION_STAT_DAILY"."RATE_CODE" NOT IN ('BKIT', 'EXPEDIA')
AND "RESERVATION_STAT_DAILY"."MARKET_CODE" NOT IN ('GOVG', 'ENT')
THEN "RESERVATION_STAT_DAILY"."RESV_NAME_ID"
ELSE NULL
END) AS "COST",
(SUM("RESERVATION_STAT_DAILY"."BUSINESS_DATE" - "RESERVATION_STAT_DAILY"."BUSINESS_DATE_CREATED")/(COUNT ("RESERVATION_STAT_DAILY"."BUSINESS_DATE_CREATED"))) AS "DIFF",
SUM(NVL("RESERVATION_STAT_DAILY"."NIGHTS",0)) AS "NIGHTS",
SUM(NVL("RESERVATION_STAT_DAILY"."ROOM_REVENUE",0)) AS "ROOM_REVENUE"
FROM "OPERA"."RESERVATION_STAT_DAILY" "RESERVATION_STAT_DAILY"
Where RESORT in ('558339','558341','4856','558340','602836','HCA','HZSD', 'TAC') and
BUSINESS_DATE < SYSDATE AND EXTRACT(year FROM "RESERVATION_STAT_DAILY"."BUSINESS_DATE_CREATED") >=2016
GROUP BY
"RESERVATION_STAT_DAILY"."RESORT",
"RESERVATION_STAT_DAILY"."BUSINESS_DATE",
to_char("RESERVATION_STAT_DAILY"."BUSINESS_DATE",'MON-yyyy'),
Extract(day from "RESERVATION_STAT_DAILY"."BUSINESS_DATE"),
Extract(month from "RESERVATION_STAT_DAILY"."BUSINESS_DATE"),
Extract(year from "RESERVATION_STAT_DAILY"."BUSINESS_DATE"),
"RESERVATION_STAT_DAILY"."SOURCE_CODE",
"RESERVATION_STAT_DAILY"."MARKET_CODE",
"RESERVATION_STAT_DAILY"."RATE_CODE",
"RESERVATION_STAT_DAILY"."RESV_NAME_ID",
( CASE
WHEN (("RESERVATION_STAT_DAILY"."SOURCE_CODE" = 'GDS') AND ("RESERVATION_STAT_DAILY"."RATE_CODE" != 'BKIT' OR "RESERVATION_STAT_DAILY"."RATE_CODE" != 'EXPEDIA'
)) THEN 'GDS'
ELSE 'Other'
END )
答案 0 :(得分:4)
清理代码的一些常规技巧,以及解决方案:
正如其他人所说,NOT IN
条款在这里是完美的。将它们替换为!=
比较的大块。您还希望COUNT
和SUM
函数位于CASE
语句之外,如下所示。
SELECT
...
CASE WHEN "RESERVATION_STAT_DAILY"."SOURCE_CODE" = 'GDS'
AND "RESERVATION_STAT_DAILY"."RATE_CODE" NOT IN ('BKIT', 'EXPEDIA', ...)
AND "RESERVATION_STAT_DAILY"."MARKET_CODE" NOT IN ('GOVG', 'ENT', ...)
THEN 'GDS'
ELSE 'Other'
END AS "BizUnit",
COUNT(DISTINCT CASE WHEN "RESERVATION_STAT_DAILY"."SOURCE_CODE" = 'GDS'
AND "RESERVATION_STAT_DAILY"."RATE_CODE" NOT IN ('BKIT', 'EXPEDIA', ...)
AND "RESERVATION_STAT_DAILY"."MARKET_CODE" NOT IN ('GOVG', 'ENT', ...)
THEN "RESERVATION_STAT_DAILY"."RESV_NAME_ID"
ELSE NULL
END) AS "COST",
...
FROM
"OPERA"."RESERVATION_STAT_DAILY" "RESERVATION_STAT_DAILY"
WHERE
...
GROUP BY
...
您的代码超过570行。有些人认为1/10的代码太多了。请注意我是如何剪掉不直接适用于您的问题的部分的?这就是您创建minimal, complete, and verifiable working example.
的方法答案 1 :(得分:3)
只是一些评论(评论时间太长):
AND ("RESERVATION_STAT_DAILY"."RATE_CODE" != 'BKIT' OR "RESERVATION_STAT_DAILY"."RATE_CODE" != 'EXPEDIA' )
?想一想。什么时候不满足这个条件?费率代码将始终不同于一个值或另一个(通常是两个),除了NULL,其结果是“未知”。THEN COUNT(DISTINCT "RESERVATION_STAT_DAILY"."RESV_NAME_ID") ELSE COUNT(DISTINCT "RESERVATION_STAT_DAILY"."RESV_NAME_ID") END) AS "COST"
。所以在任何情况下你都算不同RESV_NAME_ID
。为什么CASE
呢?RESV_NAME_ID
分组时,COUNT(DISTINCT "RESERVATION_STAT_DAILY"."RESV_NAME_ID")
在一个组中始终只能为1。sum(NVL("RESERVATION_STAT_DAILY"."NIGHTS",0))
和sum(NVL("RESERVATION_STAT_DAILY"."ROOM_REVENUE",0))
:SUM
忽略空值,因此您无需在添加之前创建这些零。总和可以为空,因此您可能需要NVL(SUM(NIGHTS), 0)
。FROM
,GROUP BY
等)。