我試圖在我的資料庫中只獲取 8 月份,然后計算 8 月份的性能有多少次,但我不知道該怎么做。
我已經給出了迄今為止我創建的代碼。
SELECT f.FILM_NAME, COUNT(p.PERFORMANCE_DATE), SUM(p.TAKINGS), p.PERFORMANCE_DATE
FROM A2_PERFORMANCE p, A2_FILM f
WHERE p.PERFORMANCE_DATE LIKE TO_DATE('08-2021', 'MM-YY')
GROUP BY f.FILM_NAME, p.PERFORMANCE_DATE
ORDER BY f.FILM_NAME
我目前正在努力實作這一目標:
-- FILM_NAME Performances Total Takings
-- --------------------------- ------------ ----------------------
-- It Happened One Night 39 £63,571
-- Modern Times 38 £58,332
-- Parasite 23 £37,195
-- Knives Out 22 £34,362
-- Citizen Kane 25 £32,711
-- The Wizard of Oz 18 £21,716
-- Avengers: Endgame 18 £17,081
uj5u.com熱心網友回復:
您可以將日期轉換為字串并將它們與 '08-2021' 進行比較(不是按照您所做的方式 - 您必須先將格式應用于日期本身),但這效率低下。
您還可以將日期截斷到月初并與 date 進行比較'2021-08-01',但這也是低效的。
“低效率”來自兩個來源,一個較小,一個非常大。較小的一個是必須將函式應用于表中的資料。真正重要的一個與索引有關:如果您的查詢經常根據日期進行過濾,那么您將從索引日期列中受益 - 但如果您的過濾器首先將函式應用于日期列,則無法使用索引。
那么,該怎么做呢?最好的(特別是如果你的“日期”可能有除午夜以外的時間部分)是這樣的:
...
where p.performance_date >= date '2021-08-01'
and p.performance_date < date '2021-09-01'
...
請注意,它總是兩個不等式,第一個是非嚴格的,第二個是嚴格的。
相反,如果您使用performance_date between [Aug 1] and [Sep 1](在偽代碼中),這將給出錯誤的答案 - 這使得第二個不等式也不嚴格,因此您將包括日期為 9 月 1 日的表演,如果它們以一天中的午夜。并且between [Aug 1] and [Aug 31]會錯過 8 月 31 日的一切,除了午夜。
最好不要使用 BETWEEN 而是使用兩個顯式不等式,正如我所展示的。
uj5u.com熱心網友回復:
你目前正在做:
WHERE p.PERFORMANCE_DATE LIKE TO_DATE('08-2021', 'MM-YY')
您提供的是 4 位年份值 (2021),但僅在格式模型中提供了 YY,而不是 YYYY。現在,默認情況下,Oracle 對這類事情很寬容——有些人可能會說,這無濟于事——所以這將適用于這種情況。但這不是很好的做法,而且TO_DATE('08-2021', 'MM-YYYY')會更好。無論哪種方式,這都會給您當月第一天的午夜。你可以提供多一點簡單地用日期文字:DATE '2021-08-01'。
LIKE是一個模式匹配條件,并比較字串,而不是日期。您正在使用會話的 NLS_DATE_FORMAT 設定強制對列值和提供給字串的固定日期進行隱式轉換。您也不包含任何通配符,使其等效于=. 因此,使用常見的 NLS 設定,您實際上是在執行以下操作:
WHERE TO_CHAR(p.PERFORMANCE_DATE, 'DD-MON-RR') = TO_CHAR(DATE '2021-08-01', 'DD-MON-RR')
使用該 NLS 設定,您將匹配 8 月 1 日的任何值 - 盡管它會匹配 1921 年等以及 2021 年的資料(如果有的話)。使用更精確的 NLS 設定,您可能會執行以下操作:
WHERE TO_CHAR(p.PERFORMANCE_DATE, 'YYYY-MM-DD HH24:MM:SS') = TO_CHAR(DATE '2021-08-01', 'YYYY-MM-DD HH24:MI:SS')
它只會匹配 8 月 1 日午夜的值。
要匹配整月,您可以使用顯式掩碼,而不是隱式轉換;并且您只需要轉換列值,因為無論如何您都可以以您想要的格式提供固定值:
WHERE TO_CHAR(p.PERFORMANCE_DATE, 'YYYY-MM') = '2021-08'
或者,如果您愿意(我不喜歡,但這不是我的代碼):
WHERE TO_CHAR(p.PERFORMANCE_DATE, 'MM-YYYY') = '08-2021'
但是這種轉換將阻止使用該列的正常索引。我建議提供一個日期范圍以避免任何轉換:
WHERE p.PERFORMANCE_DATE >= DATE '2021-08-01'
AND p.PERFORMANCE_DATE < DATE '2021-09-01'
它將查找該列在 8 月 1 日午夜或之后以及9月 1 日午夜之前的所有行。
uj5u.com熱心網友回復:
如果您正在尋找八月的所有活動,而不管年份,您可以將您的列轉換為 'MON' 的字符并將其與 'AUG' 匹配:
SELECT f.FILM_NAME, COUNT(p.PERFORMANCE_DATE), SUM(p.TAKINGS),p.PERFORMANCE_DATE
FROM A2_PERFORMANCE p, A2_FILM f
WHERE TO_CHAR(p.PERFORMANCE_DATE,'MON') ='AUG'
GROUP BY f.FILM_NAME, p.PERFORMANCE_DATE
ORDER BY f.FILM_NAME
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/388839.html
上一篇:如何在docker容器之間連接到oracle資料庫?
下一篇:將多行(2列)旋轉為一行
