There are tables of users and questions:

Questions:
Id
Question

Variants:
Id
QuestionId
Variant istrue

ResultsTable:
Id
QuestionId
Userid
Variantid

How to make a check that in the VariantId field it would be possible to enter the Id of only the option to which the answer belongs, and not any of the questions?

Example: Question 1- How much is 2 + 2?
Option id 1 = 8; id 2 = 4
ResultsTable - User 1 answers question 1 with answer id 2 (that is, true)
Question 2- Who is faster?
Option id 331 = "snail"; id 332 = "Porsche without wheels"
Without testing, question 1 can be answered with the option from question 2, which is not true ...

  • To be honest, I did not understand anything. Give examples of the source data and what results should be obtained. - Ella Svetlaya
  • @ "Ella Svetlaya" added - Rakzin Roman
  • You need to rebuild the logic, the table structure is not organized correctly. - Ella Svetlaya

2 answers 2

Normal constraints (check constraints) will not work in your case because when checking the correctness of the inserted value of one attribute you need to view the attribute values ​​of another table. And to identify the connection between them, you need a separate request. But requests to insert into the conditions of the limitations of the DBMS as a rule do not give.

You can write a trigger that will do all the necessary checks (in it, how many you want queries you can perform), triggered by inserting / changing values ​​in the ResultsTable table. If the values ​​are not correct, then we throw an exception. But here it is important that your database supports triggers. SQL-Server, as I recall, supports.

You can also make a unique Variants index (QuestionId, Id) and set the foreign key on the ResultsTable (QuestionId, VariantId) on it. It is more universal.

But first of all think about the structure of your base. From each entry in the Variants table, you can get a QuestionID. That is, for each record from the ResultsTable, then a QuestionID is available (via Variants), and you push another 1 QuestionID there. And it should coincide with the QuestionID of Variants. This is a duplication of data. Sometimes it is justified (for example, for performance reasons), but most often it only brings integrity problems and increases the size of the base. The easiest way to remove the QuestionID from the ResultsTable and all problems will be solved. However, it is necessary to rewrite database requests from the application using it.

  • @ "Yury Plinto" how to remove QuestionID? But how to find out then what question the user answered ... and which option? - Rakzin Roman
  • one
    @ "Rakzin Roman", you yourself said that you do not need a situation where the user answers the question with an option from another question. So you can determine the question clearly from the table Variants. Just in queries to the ResultsTable will have to add a join (union) with Variants. For example, instead of SELECT UserID, QuestionID, VariantID FROM ResultsTable; becomes SELECT rt.UserID, v.QuestionID, rt.VariantID FROM ResultsTable rt JOIN Variants v ON rt.VariantID = v.VariantID; - Yury Plinto
  • one
    @ "Rakzin Roman" Moreover, this association in one form or another is present in some of your requests, I am sure of that. Let's say you need to find out if the user chose the correct option. You then also combine in the query ResultsTable and Variants. Of course, QuestionID duplication can make database queries a bit faster. I do not know how critical the performance is in your project. But if there are no problems with speed and is not foreseen, then remove this denormalization. Get rid of problems with integrity, and at the same time reduce the size of the base. - Yury Plinto

Create a unique index Variants (QuestionId, Variant).

Create Index ResultsTable (QuestionId, VariantId).

Install FK Constraint.

  • tell me what it means to install FK Constraint.? Is that the key to what? - Rakzin Roman
  • Foreign key can point to primary key or unique. We have a second case. This should allow to insert into the ResultsTable only those QuestionId / VariantId combinations that are in the Variants table. - Yury Plinto