Reputation: 3074
I have a table in an application for which the current schema is:
CREATE TABLE quotes
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
quote_request_id INT UNSIGNED NOT NULL,
quote_amount DECIMAL(12, 2) NOT NULL,
accepted TINYINT UNSIGNED NOT NULL DEFAULT 0,
FOREIGN KEY (quote_request_id) REFERENCES quote_requests(id)
) Engine=InnoDB;
I want to enforce a constraint such that only one quote can be accepted for a given quote request - i.e. an UPDATE or INSERT query should fail if it attempts to modify the table such that two or more rows with the same quote_request_id
value will have an accepted
value of 1.
Is this possible in MySQL? Enforcing constraints such as foreign keys, uniqueness of columns other than the primary key etc. work fine, and I can find information about applying a UNIQUE constraint to multiple columns, but I can't find anything about more complex constraints which involve multiple columns.
Upvotes: 2
Views: 345
Reputation: 115630
If you want to do this without triggers, you can add another table where only accepted quotes will be stored - and you can remove the accepted
column from the quotes
table:
CREATE TABLE quotes
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
quote_request_id INT UNSIGNED NOT NULL,
quote_amount DECIMAL(12, 2) NOT NULL,
--- accepted TINYINT UNSIGNED NOT NULL DEFAULT 0, --- removed
FOREIGN KEY (quote_request_id) REFERENCES quote_requests(id)
UNIQUE KEY (quote_request_id, id) --- needed for the FK below
) Engine=InnoDB;
CREATE TABLE quotes_accepted
(
id INT UNSIGNED NOT NULL PRIMARY KEY,
quote_request_id INT UNSIGNED NOT NULL,
UNIQUE KEY (quote_request_id), --- this ensures there is only one
--- accepted quote per request
FOREIGN KEY (quote_request_id, id)
REFERENCES quotes(quote_request_id, id)
) Engine=InnoDB;
Upvotes: 1
Reputation: 3074
Answered by a_horse_with_no_name, but in a comment so it can't be accepted:
"I don't think this is possible without reverting to a trigger in MySQL because MySQL does not support partial indexes."
Upvotes: 0
Reputation: 80657
You mean you want a UNIQUE
like this:
UNIQUE `quote_accepts` (`quote_request_id`, `accepted`)
where, for a repeat pair of quote_request_id
& accepted
, the INSERT
will fail.
Upvotes: 0