我正在使用postgres數據庫,我的問題包括兩個表格,它們的簡化版本如下。PostgreSQL插入語句
CREATE TABLE events(
id SERIAL PRIMARY KEY NOT NULL,
max_persons INTEGER NOT NULL
);
和
CREATE TABLE requests(
id SERIAL PRIMARY KEY NOT NULL,
confirmed BOOLEAN NOT NULL,
creation_time TIMESTAMP DEFAULT NOW(),
event_id INTEGER NOT NULL /*foreign key*/
);
有n
事件和每個事件最多可以有events.max_persons
參與者。新的請求需要確認並且有效期最長爲30分鐘。在這段時間之後,如果沒有確認,請求將被忽略。
現在什麼,我想要做的只插入一個新的request
,當所有的確認請求,以及目前仍然有效的所有請求,但沒有證實的總和,小於events.max_persons
。
我已經有查詢來選擇單個事件。這裏是它的一個簡化版本,只是給你一個想法,它應該如何工作
SELECT
e.id,
SUM(CASE WHEN r.confirmed = 1 THEN 1 ELSE 0 END) AS number_confirmed
SUM(CASE WHEN r.creation_time > (CURRENT_TIMESTAMP - INTERVAL '30 MINUTE') AND r.confirmed = 0 THEN 1 ELSE 0 END) AS number_reserved,
e.max_persons
FROM events e, requests r
WHERE l.id = ?
AND r.event_id = e.id
AND (r.confirmed = 1 OR r.creation_time > (CURRENT_TIMESTAMP - INTERVAL '30 MINUTE'))
GROUP BY e.id, e.max_persons
HAVING SUM(CASE WHEN r.confirmed = 1 OR (r.creation_time > (CURRENT_TIMESTAMP - INTERVAL '30 MINUTE')) THEN 1 ELSE 0 END) < e.max_persons";
難道不可能性與一個單一的INSERT實現這一目標 - 命令?
你好,對於最近的答案抱歉。目前我通過運行查詢來解決我的問題,該查詢得到max_persons和number_booked/number_reserved之間的差異,並只執行插入語句,如果它大於0。這是一種可行的做法嗎?還有一個問題,如果我使用SERIALIZABLE交易,我可以解決兩個人同時報名參加同一個活動的問題,但只剩下一個地方嗎? – PrototypeX7
您目前的技術很容易受到我在答覆中指出的問題的影響 - 如果兩個此類事務並行運行,並且只有一個地方是免費的,則它們都會添加新的請求。 SERIALIZABLE無法實現。其中一個事務會因序列化錯誤而終止,並且必須重試。在重試期間,它會顯示該事件已經預訂完畢。 –
謝謝,試試看! – PrototypeX7