簡體   English   中英

在選擇Oracle SQL的情況下無法區分計數

[英]Count Distinct Not Working in Case Select Oracle SQL

我有一個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 )

一些清理代碼的一般技巧,以及一個解決方案:

正如其他人所說, NOT IN這里NOT IN子句將是完美的。 將它們替換為!=比較的大塊。 您還希望COUNTSUM函數位於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是太多的代碼。 請注意,我是如何剔除與您的問題不直接相關的部分的? 這就是您創建最小,完整和可驗證的工作示例的方式。

僅有幾句話(評論太久了):

  1. AND ("RESERVATION_STAT_DAILY"."RATE_CODE" != 'BKIT' OR "RESERVATION_STAT_DAILY"."RATE_CODE" != 'EXPEDIA' ) 考慮一下。 何時不滿足該條件? 費率代碼將始終與一個值或另一個值(通常都是兩個值)不同,但NULL除外,其結果是“未知”。
  2. THEN COUNT(DISTINCT "RESERVATION_STAT_DAILY"."RESV_NAME_ID") ELSE COUNT(DISTINCT "RESERVATION_STAT_DAILY"."RESV_NAME_ID") END) AS "COST" 因此,無論如何,您RESV_NAME_ID計算出不同的RESV_NAME_ID 為什么CASE呢?
  3. 當您按RESV_NAME_IDCOUNT(DISTINCT "RESERVATION_STAT_DAILY"."RESV_NAME_ID")始終只能為1。
  4. sum(NVL("RESERVATION_STAT_DAILY"."NIGHTS",0))sum(NVL("RESERVATION_STAT_DAILY"."ROOM_REVENUE",0))SUM忽略空值,因此在將它們相加之前不必將這些零值設為零。 然而,總和可以為null,因此您可能需要NVL(SUM(NIGHTS), 0)
  5. 關於可讀性:所有大寫字母的查詢都很難閱讀。 請使用小寫字母或將兩者混合使用(例如,SQL關鍵字使用大寫字母)。 由於沒有一列包含空格或類似內容,因此您不需要引號。 由於只涉及一個表,因此不需要表限定符。 如果這樣做的話,您應該為該表使用一個簡短的別名,並使用它代替整個名稱。 並且您應該使用縮進來格式化查詢,因此乍一看,我們會看到子句( FROMGROUP BY等)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM