【问题标题】:Insert if table is empty OR join condition is fulfilled如果表为空或满足连接条件则插入
【发布时间】:2013-10-26 12:52:00
【问题描述】:

对于铁杆 SQLers 来说是个不错的谜题。

2 个表格:拍卖和出价。

CREATE TABLE auctions
(
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
created_at INT,
timer INT DEFAULT 10,
user_id BIGINT UNSIGNED
)ENGINE=InnoDB;

CREATE TABLE bids
(
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
created_at INT,
user_id BIGINT UNSIGNED,
auction_id BIGINT UNSIGNED
)ENGINE=InnoDB; 

给定拍卖,如果满足以下条件之一,用户可以对其出价:

  • 最后一个出价的创建时间少于 auction.timer 秒前
  • 拍卖没有出价

简而言之:这是一个在 x 秒内没有被任何人关注的最后一个出价用户赢得拍卖的游戏。

此处不允许交易。

这是我的尝试:

INSERT INTO bids (user_id, auction_id) 
SELECT 1, a.id
FROM auctions AS a, bids AS b
WHERE a.id = b.auction_id
AND a.user_id IS NULL
AND a.id = 1
AND (UNIX_TIMESTAMP() - b.created_at) < a.timer
LIMIT 1

它有效,但我不知道如何将“给定拍卖 id 的或没有出价”逻辑放入其中。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    如果我对您的理解正确,您需要一个外部连接(可选)来进行出价。像这样:

    INSERT INTO bids (user_id, auction_id) 
    SELECT 1, a.id
    FROM auctions AS a
    left outer join bids AS b
    ON a.id = b.auction_id
    AND (UNIX_TIMESTAMP() - b.created_at) < a.timer
    where
    (a.user_id IS NULL
    AND a.id = 1
    
    ) OR
    b.id IS NULL     --this will be true if there is no bid present
    LIMIT 1
    

    【讨论】:

    • 这里是解决方案(参数的问号):INSERT INTO bids (user_id,auction_id) SELECT ?, a.id FROM auction AS a LEFT OUTER JOIN bids AS b ON a.id = b.auction_id哪里 a.user_id 为 NULL 并且 a.id = ? AND ((UNIX_TIMESTAMP() - b.created_at)
    【解决方案2】:

    您可以使用子查询来确定拍卖中是否有任何出价。也许是这样的:

    OR NOT EXISTS (SELECT * FROM bids WHERE auction_id = ?)
    

    【讨论】:

    • 谢谢你,brian,但是如果包含这个子查询,查询会是原子的吗?
    • 可能不会,但我认为 JOIN 也不会是原子的。您可能必须先锁定表。
    猜你喜欢
    • 2019-03-01
    • 1970-01-01
    • 2023-04-05
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    相关资源
    最近更新 更多