我有以下查詢來獲取需要每月提醒一次的約會,如果他們還沒有完成的話。我想從當前日期獲取過去 30, 60, 90, ... 的記錄。
SELECT
a.*
FROM
appointments a
WHERE
DATEDIFF(CURDATE(), a.appointment_date) % 30 = 0
有沒有另一種方法不使用 DATEDIFF 來實作這一點?我想提高這個查詢的性能。
uj5u.com熱心網友回復:
您可以使用以下查詢將約會當月的日期與今天的當月日期進行比較。
我們還測驗我們是否是月底的最后一天,以便在月底到期。例如,如果我們是 2 月 28 日(不是閏年),我們將接受該月的天數>= 28,即 29、30 和 31,否則會被錯過。
此方法與您當前的系統存在相同的問題,即會錯過周末的約會。
select a.*
from appointements a,
(select
day(now()) today,
case when day(now())= last_day(now()) then day(now()) else 99 end lastDay
) days
where d = today or d >= lastDay;
uj5u.com熱心網友回復:
你只想要未來30天的約會?它們存盤為DATE? 或者DATETIME?好吧,這在任何一種情況下都有效:
SELECT ...
WHERE appt_date >= CURDATE() INTERVAL 30 DAY
AND appt_date < CURDATE() INTERVAL 31 DAY
如果您有(或任何以 開頭的INDEX(appt_date)索引),則查詢將是有效的。 appt_date
諸如此類DATE()的東西不是“可分析的”,并且會阻止使用索引。
如果您的目標是嘮叨客戶,我在您的查詢中看不到任何內容,以防止一遍又一遍地嘮叨每個人。這可能需要一個單獨的“嘮叨”表,可以洗掉對嘮叨感到滿意的客戶。那么性能就不會成為問題,因為表會很小。
uj5u.com熱心網友回復:
如果您主要關心的是加快查詢速度,我們可以添加一個 int 列來比較天數并為其編制索引。然后,我們添加觸發器來計算 Unix 周期開始之間的 datediff 模數:01/01/1970(或任何其他日期,如果您愿意)并將結果存盤在此列中。
這將占用少量存盤空間,并減慢插入和更新操作。當我們當時添加或修改一個約會時,這不會引起注意,我懷疑這是一般情況。
當我們查詢我們的表時,我們計算今天的天值,這將花費很少的時間,因為它只會執行一次,并將它與天數列進行比較,因為它被索引并且不涉及計算,所以很快。
最后,我們運行您當前的查詢并使用 explain 查看它,以查看即使我們已索引列 date_ ,該索引也不能用于此查詢。
CREATE TABLE appointments ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, date_ date, days int ); CREATE INDEX ix_apps_days ON appointments (days);? ?
CREATE PROCEDURE apps_day() BEGIN UPDATE appointments SET days = day(date_); END
?
CREATE TRIGGER t_apps_insert BEFORE INSERT ON appointments FOR EACH ROW BEGIN SET NEW.days = DATEDIFF(NEW.date_, '1970-01-01') % 30 ; END;?
CREATE TRIGGER t_apps_update BEFORE UPDATE ON appointments FOR EACH ROW BEGIN SET NEW.days = DATEDIFF(NEW.date_, '1970-01-01') % 30 ; END;?
insert into appointments (date_) values ('2022-01-01'),('2022-01-01'),('2022-04-15'),(now());?
update appointments set date_ = '2022-01-12' where id = 1;?
select * from appointments編號 | 日期_ | 天 -: | :--------- | ---: 1 | 2022-01-12 | 14 2 | 2022-01-01 | 3 3 | 2022-04-15 | 17 4 | 2022-04-22 | 24
select * from appointments where DATEDIFF(CURDATE() , '1970-01-01') % 30 = days;編號 | 日期_ | 天 -: | :--------- | ---: 4 | 2022-04-22 | 24
explain select DATEDIFF(CURDATE() , '1970-01-01') from appointments where DATEDIFF(CURDATE() , '1970-01-01') = days;編號 | 選擇型別 | 表| 隔斷 | 型別 | 可能的鍵 | 關鍵 | key_len | 參考 | 行 | 過濾 | 額外的 -: | :------------ | :----------- | :--------- | :--- | :------------ | :----------- | :-------- | :---- | ---: | --------: | :---------- 1 | 簡單 | 約會 | 空 | 參考 | ix_apps_days | ix_apps_days | 5 | 常量 | 1 | 100.00 | 使用索引
CREATE INDEX ix_apps_date_ ON appointments (date_);?
SELECT a.* FROM appointments a WHERE DATEDIFF(CURDATE(), a.date_) % 30 = 0編號 | 日期_ | 天 -: | :--------- | ---: 4 | 2022-04-22 | 24
explain SELECT a.* FROM appointments a WHERE DATEDIFF(CURDATE(), a.date_) % 30 = 0編號 | 選擇型別 | 表| 隔斷 | 型別 | 可能的鍵 | 關鍵 | key_len | 參考 | 行 | 過濾 | 額外的 -: | :------------ | :---- | :--------- | :--- | :------------ | :--- | :-------- | :--- | ---: | --------: | :---------- 1 | 簡單 | 一個 | 空 | 全部 | 空 | 空| 空 | 空| 4 | 100.00 | 使用哪里
db<>在這里擺弄
uj5u.com熱心網友回復:
好的,讓我們暫時將日期和日期差異放在一邊。查看問題,此人正試圖查找過去不一定有另一個約會的所有約會。例如與醫生進行后續預約。“一個月后回來看看情況發生了哪些變化”。這讓我想到約會表中可能有一些患者 ID。因此,這可能會將問題轉為查看過去 30、60 或 90 天前的情況,以查看將來是否安排了相應的約會。如果已安排好,患者無需電話提醒即可進入辦公室。
也就是說,我會以不同的方式開始,讓所有 DID 患者在過去 90 天內進行預約,并查看他們是否已經(或沒有)在后續計劃中進行了后續預約。這樣,辦公室人員可以與所述患者聯系以獲取日歷。
首先在過去 90 天內為任何給定患者獲取所有最大預約。如果某人在 90 天前進行了預約,并在 59 天進行了隨訪,那么他們可能只關心最近的預約以確保有后續。
select
a1.patient_id,
max( a1.appointment_date ) MostRecentApnt
from
appointments a1
WHERE
a1.appointment_date > date_sub( a1.appointment_date, interval 90 day )
group by
a1.patient_id
現在,從這個固定的串列和開始日期,我們關心的是,距上次約會還有多少天。是X天嗎?只需使用 datediff 和排序。您可以直觀地看到有多少天。通過嘗試將它們分成 30 天、60 天或 90 天的存盤桶,只知道自上次約會以來的天數可能就像按降序排序一樣容易,最舊的約會首先被呼叫,而不是剛剛發生的約會。甚至可能在 20 天后切斷通話清單,但仍未預約并接近預期的 30 天。
SELECT
p.LastName,
p.FirstName,
p.Phone,
Last90.Patient_ID,
Last90.MostRecentApnt,
DATEDIFF(CURDATE(), Last90.appointment_date) LastAppointmentDays
FROM
( select
a1.patient_id,
max( a1.appointment_date ) MostRecentApnt
from
appointments a1
WHERE
a1.appointment_date > date_sub( a1.appointment_date, interval 90 day )
group by
a1.patient_id ) Last90
-- Guessing you might want patient data to do phone calling
JOIN Patients p
on Last90.Patient_id = p.patient_id
order by
Last90.MostRecentApnt DESC,
p.LastName,
p.FirstName
有時,僅僅為直接問題提供答案并沒有得到正確的需要。希望我能更準確地滿足預期的最終結果需求。同樣,上述內容意味著加入患者表以進行后續呼叫以安排約會。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/464450.html
上一篇:JMH-較低級別的基準測驗
