Basically we have the same problem as this question: ON DUPLICATE KEY update (with multiple where clauses)
But we can't have unique keys for the keys of reference because we need duplicates of both.
Is there a way to do this with one query?
We have a unique identifier, and also need to record date, and increment a value, but also be able to update/insert without making multiple queries.
Please excuse me if I'm understanding you incorrectly, but it seems to me that what you want can in fact be done with the UNIQUE contraint mentioned in the question you're referencing.
Are you aware that you can create a UNIQUE constraint on more than one column? That is, the combination of the 2 columns is unique, but the columns themselves don't have to be.
In your case, you would use ALTER TABLE table ADD CONSTRAINT uq_table_id_date UNIQUE (id, date).
Related
The table already has duplicates entries. I want to create a unique constraint in MQSL DB without deleting the existing duplicates. If any duplicate entries coming onwards then it will show an error. Given blow queries not working in MYSQL.
ALTER TABLE presence
ADD CONSTRAINT present uniqueness UNIQUE (employee_id,roll_number) where id >10000;
or
ALTER TABLE presence
ADD CONSTRAINT present uniqueness UNIQUE (employee_id,roll_number) where id <> (343,34534,34534)
Do we have something like that solution in SQL?
Add an additional column to the table that indicates the existing values.
Set it to NULL for the existing values. And give it a constant value, say 1, for the new rows. Then create a unique index or constraint on this column:
alter table t add constraint unique (employee_id, is_old)
Actually, I realize that you probably don't want duplicates with singleton old values and new values. That is just an issue of setting the value to NULL only for duplicates in the history. So, one row would have a constant value (say 1) in the historical data.
MySQL allows duplicate values on NULL, which is why this works.
I know that foreign keys need not reference only primary keys but they can also reference a field that has a unique constraint on it. For my scenario, I am setting up a quiz where for each test, I have a set of questions. My table design is like this
The point is, in my 2nd table where I will put all the answer options, I want the question number field to link to the first table question number. How do I do this? Or is there an alternative to this design?
Thank you
Ideally there should be a question_id primary key column in the test_question table, and you would use this as the foreign key in the test_answer table.
With your composite primary key in the test_question table, you should make a corresponding composite foreign key:
CONSTRAINT FOREIGN KEY (test_id, question_no) REFERENCES test_question (test_id, question_no)
This is in addition to the foreign key just for the test_id column.
Add another table purely for answers, and link them via the question_no field.
A DB table should hold information on one sort of item. Questions and answers are separate sorts of information so should be in separate tables. Adding a separate table also allows changes to questions and answers independently. Additionally, if they are separate, you could add a language field to each table and have a multi-lingual quiz
Short answer:
You can JOIN on any columns or expressions. There is no "requirement" for a FOREIGN KEY, PRIMARY KEY, UNIQUE, or anything else.
Long answer:
However,... For performance (in large tables), some things make a difference.
If you are JOINing to a PK, Unique key, or even an indexed column, the query cold run faster.
Why have a FOREIGN KEY? An FK is two things:
A "constraint" that says that the value must exist in the other table. Also, with things like ON DELETE CASCADE, it can provide actions to take if the indicated row is removed. The constraint requires looking in the other table each time a write occurs (eg INSERT).
An Index. That is, specifying a FK automatically adds an INDEX (if not already present) to make the constraint faster.
Getting the id
Here is the "usual" way to do a pair of inserts, where you need the second to 'point' to the first:
INSERT INTO t1 ... -- with an AUTO_INCREMENT id
grab LAST_INSERT_ID() -- that id
INSERT INTO t2 ... -- and include the id from above
For AUTO_INCREMENT to work it must be the first column of some key. (Note: a PRIMARY KEY is a UNIQUE is a key (aka INDEX).)
Optionally you can specify a FK on the second table to point out the connection between the tables.
And, as spelled out in other answers, a FK could involve more than one column.
Entities and Relations
Sometimes, a set of tables like yours is best 'designed' this way:
Determine the "entities": users, tests, questions, answers
Relations and whether they are 1:1, 1:many, or many:many... Users:test is many-to-many; tests:questions is 1:many (unless you want questions to be shared between tests).
Answers is more complex since each 1 answer depends on the user and question.
1:1 -- rarely practical; may as well merge the tables together.
1:many -- a link (FK?) in one table to the other.
many:many -- need a bridge table with (usually) 2 columns, namely ids linking to the two tables.
I am learning MySQL and used the ON DUPLICATE KEY UPDATE, what this does, if I am not mistaken, when it found a duplicate; it will update the row. So, to my question, is there something like ON DUPLICATE KEY INSERT? like when it found a duplicate, it will still insert the data into the table?
No, there is no way to insert a row that has duplicate values in columns that are constrained against duplicate values. If you could, the result would be that the database would be in a state that violates its own constraints.
You would have to drop any unique key or primary key constraints on the table to allow duplicates in the respective columns.
I'm trying to create a unique index constraint for two columns (id_1 and id_2) with the following condition:
If two different rows have the same value in the id_2 column, their values in the id_1 column must also be the same.
Is it possible?
Thanks.
There is no declarative constraint to support such a restriction. The scenario you describe does not satisfy the requirements for a unique constraint. (You can create the constraint, but you won't be able to add more than one row with identical values for id_1 and id_2.
If your intent is to reject an insert or an update based on this restriction, you might be able to accomplish this with a row-level trigger.
You could do that by building a query that checks these rows and integrate it in a trigger. You won't be able to do that with a constraint and certainly not with a unique constraint. A unique constraint forces rows to have unique values. That means that for the field or fields in the constraint no two rows can have the same value.
That is not possible. A unique constraint on id_1 and id_2 will force each row to have a different (unique) combination of id_1 and id_2. That's the exact opposite of what you are describing.
You could possibly enforce your requirement by using a trigger, but given the small amount of information provided by you, I can't say if it would be the best solution.
A composite foreign key could also be the solution, but I don't know what id_1 and id_2 refer to, so it's hard to say, really.
I may have either misunderstood how to use the ON DUPLICATE KEY syntax, alternatively my database structure needs some work but here goes.
I have a table (bookings-meta) which represents meta data associated with another table (bookings) , different rows in the bookings table may or may not have specific meta data associated with them in the other table.
The bookings-meta table has the following columns, meta_id (primary key), booking_id, key and value.
From my understanding, to use ON DUPLICATE KEY I need to know what in this case is the meta_id, often this isn't the case, I'm trying to simply push a key, value pair to the table using the booking_id, so if the particular key exists then its replaced otherwise its inserted.
At the moment I have a seperate query to try to select the row, if its found then I UPDATE, if not then its an INSERT.
Is there a way of doing an insert/update in one query without using ON DUPLICATE KEY or have I missed a trick with this one?
If possible, I'd drop the meta_id column entirely and turn booking_id and key into a composite primary key. That'll save space in your table, allow use of ON DUPLICATE KEY, and be cleaner in general.