SQL Structure to Store Surveys and Answers - Build Tables and Queries Based on User Data? - sql

I'm a total newbie when it comes to SQL. I'm making a site in ASP.NET for doing surveys. A privileged admin user will be able to build a survey. Then lots of other people will respond to the survey.
Once I have the set of questions for a new survey, what is the best way to automatically construct a table and an INSERT query to store the responses?
UPDATE
Thanks for the quick responses! I'm still a little unclear on how survey responses would best be stored in this scenario. Would each respondent get a row of the table? And if so, would the columns be "answer given for question k of the survey identified by the entry in column 1"?

You dont want to build a new table for each survey.
Create a surveys table (SurveyID, UserID, Name, etc)
Create a Questions Table (QuestionID, SurveyID, QuestionText, SortOrder, etc)
optionally, Create an Options table, assuming you have multiple choice type questions (OptionID, QuestionID, OptionText, etc)
Then when someone creates a survey, you insert into the Surveys Table, referencing that person's UserID as the foriegn key, then get the newly inserted SurveyID,
Then for each question they add, insert it into the Questions table, using the above SurveyID as the foriegn key.. and so on.
EDIT to answer your edit:
Sorry I should have followed through to cover storing answers as well.
You would want another table called SurveyResponses (ResponseID, Name, etc)
And another table I'll call ResponseAnswers(ResponseAnswerID, SurveyID, ResponseID, QuestionID, AnswerText/AnswerID) Where SurveyID and ResponseID are foriegn keys to thier respective tables, and depending on wether users have multiple choice, or enter an answer, you would either store thier answer as text(varchar) or as another foriegn key to the options table.

You probably don't want to be programatically generating the schema.
Instead, have a table for surveys, for questions (which belong to surveys), for response sets (one per user), and question responses (which belong to the response sets).

I'd think of a couple of options:
Create a one-to-many Survey table and Question table, where each Question has a column DataType that has a code of the response data-type we're expecting, and optionally some other columns / related table of available options, a column that specifies if this question is multi/single choice, mandatory/optional question etc. The Answer table's Answer is serialized/desieralized/indexed/formatted etc. according to the question data-type
Consider using NoSql database to store the survey data in a similar manner

You wouldn't automatically construct the table. The table would be predefined, and the answers would be added to them. I think the best way to get started with ASP.NET these days is to dive into MVC & Linq (http://asp.net/learn)

Related

Allow One Column to Relate to Multiple Rows in Another Table [duplicate]

This question already has answers here:
Is storing a delimited list in a database column really that bad?
(10 answers)
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
For an assignment, we are supposed to be "reverse-engineering" a website and try to recreate the database structure. I have all but one column done, and I am not sure how to make it work.
For this assignment, I chose to "reverse-engineer" the Rate My Professors website. I have 4 tables: users, reviews, professors, and schools. In the website, you can save multiple professors, but that is the problem I am having for this... I don't know what datatype to set the "saved_professors" column of the "User" table. I want it to have the ids of each professor in an array, but as far as I know, you can't have the data type as an array (SET and ENUM seem close, but I am pretty sure that those won't work the way I need it to...)
Is there a way to do this? Or should I just set it to a VARCHAR or TEXT (which would just hold a list of the ids in a string)?
Note: This is not about storing a string of ids, I already know how to do that, and I know it's not the best way, that's why I was asking this question specifically... please don't mark it as "duplicate" to Is storing a delimited list in a database column really that bad?... it is a good question/answer, but it doesn't answer my question here.
You need another table.
What you're describing is a many-to-many relationship. A student can save many professors, and likewise a given professor may be saved by many students.
Every many-to-many relationship should be stored as a set of rows in a new table:
CREATE TABLE saved_professors (
user_id INT NOT NULL,
professor_id INT NOT NULL,
PRIMARY KEY (user_id, professor_id)
);
Store just one pair on each row in this table. This means that for each student, there may be many rows in this table.
See also my answer to: Is storing a delimited list in a database column really that bad?

Survey Database - additional question about table structure

I'm referencing a closed stack overflow post,
Database design for a survey
The top answer in the post gives a great overview of the tables to use for a survey database, with a good table-relationship view. My question piggybacks on the survey tables, particularly the table which stores the top level survey records. For surveys which are given in specified periods (initial survey, 6 month after, 12 month after, etc.), if the survey does not have different questions and answers (just a duplicate of the initial survey), would it make more sense to create different surveys in the top level survey table as different survey records, or would it be better to add a field in the completed survey table as a secondary identifier.
For example, if a survey (let's call it "Health assessment") has an initial survey, then one 6 month after, which would be the better solution:
make two records in the survey table - "Health assessment - initial" and "Health assessment - 6 month", so that in the completed survey table the surveyID would be different for both surveys. This would, I suppose, require records for both surveys in other tables (survey_question and survey_question_answer). Seems like a lot of duplication.
make one record in the survey table - "Health assessment", and add an additional designation in the completed survey table (answer) where the user could put "Initial" or "6-month".
Hopefully that makes sense. I think either solution might work; I just want the more optimal solution.
Keeping to this existing design; Assuming SurveyID is a unique Primary Key, the first suggestion, as you already recognized, will cause redundant data unless the intention is for the questions to change over time. The second option is not great either because I believe it would invalidate the purpose of the StartDate, EndDate, and IsOpened fields on the Survey table.
What about creating a Survey_Instance table? The Survey table would hold the Survey ID and description and the new table would hold the Start, End, and IsOpened properties for each time the survey posted. The responses could be linked via "SurveyInstanceID" and the questions could be linked to the Survey table. This has the added benefit of linking responses to a specific time frame so you could observe how the responses might change over time.

How to Make a CRUD with Relationship between more than 1 Table - GroceryCRUD

I have a simple question here regarding GroceryCRUD.
The question is: Is there a way to build a CRUD using Grocery when I have multiple relationship (JOINs)? For example: I want to have a CRUD for the following:
Table QUESTIONS
IDQuestion
IDRightAnswer
IDKnowledgeArea
Question
IDExplanation
One Record in this table would contain:
IDQuestion IDRightAnswer IDKnowledgeArea Question
10---------------2----------------------3---------------------------What is the color of the sun?
Table KnowledgeArea
ID------------Name
1--------------Phisics
2--------------Math
3--------------Astronomy
So, as this is normalized table, for those IDs (except for IDQuestion cuz it is PK and IDRightAnswer cuz its a FK) which is/are FK in the Questions table, I would like to have the correlated values (text) from Original table displayed in the grid rather than the ID itself.
So, using the same example, for the column IDKnowledgeArea in the table Questions (its a FK here) the CRUD would bring a combobox with the original values (text) in the table IDKnowledgeArea then I could chose it from there.
For example:
IDQuestion IDRightAnswer IDKnowledgeArea Question
10---------------2-----------------------Astronomy-------------What is the color of the sun?
All the CRUD tools I've seen doens't have such resource and although they provide good CRUD approach they never address this multi-relationship between the entities.
I appreciate any answer.
Thank you
Actually I gave a look on the documentation and I found this:
http://www.grocerycrud.com/documentation/options_functions/set_relation
Set a relation 1-n database relation. This will automatically create a dropdown list to the fields and show the actual name of the field and not just a primary key to the list. An example of this:
$crud->set_relation('user_id','users','username');
Thank you all

Proper Design For SQL table connecting to many other tables

I have an app where users can log comments related to any specific entity that the system has and I wanted to know if there is a "best practice" way to handle the design of the db for this kind of feature.
For example: Three current entities (tables) deal are Question, Documentation, ReferenceMaterial (self explanatory what each hold). The user can leave a comment on any one of those particular items and all comments are simply a varchar field, user id, and date of comment. EDIT: Comments can also belong to more than one entity. For example, all Question entities belong to a Quiz or Test entity. Each of those (Quiz and Test), can also have comments associated with themselves. So you could run a report to see all comments left for a test and easily just query the Comment table for every record with that test foreign key, or you could limit your query to just the comments left for questions in that test, or a particular question itself. It offered a lot of flexibility END EDIT
Right now the way that I hvae this is one Comment table with a foreign key relationship with each of the other entity tables (i.e. fkQuestion, fkDocumentation, fkReferenceMaterial, etc). So all comments in the system are stored in this table and based on what page the user is on, I conduct the join to that particular entity's records.
Is there a best practice way of doing this?
Thanks in advance for any help.

Database Table Design for storing yes, no, and quantity type responses to questions

I have a table that stores answers to checklist questions, where the checklists are in the format of yes, no, not applicable, or resolved.
Table: CHECKLIST_ANSWER
ATTRIBUTE_ID PK, FK
CHECKLIST_INSTANCE_ID PK, FK
TOGGLE_VALUE (1=yes, 2=No, 3=n/a, 4=was a no then it was resolved)
FAIL_REASON
ATTRIBUTE_ID is a foreign key to a table of questions, i.e. Was the part measured within some tolerance?
Now I want to model a checklist that would store quantity responses, i.e. How many incorrect dimensions were found on the drawing?
I feel confident that I can store these questions in my same table as the yes/no/na type attributes, but can I utilize the the same table to store the quantity value? Should I add a new column say QUANTITY_VALUE ? And then either QUANTITY_VALUE or TOGGLE_VALUE would be null depending on the attribute.
Table: CHECKLIST_ANSWER
ATTRIBUTE_ID PK, FK
CHECKLIST_INSTANCE_ID PK, FK
TOGGLE_VALUE (1=yes, 2=No, 3=n/a, 4=was a no then it was resolved)
QUANTITY_VALUE
FAIL_REASON
The goal of this database application is to move paper and excel checklists online and capture into Oracle to give provide more efficient collection of metrics and then better aggreagation of the inputs. Am I asking for trouble down the road by blending two into one table? Or should I create a table, CHECKLIST_QTY_ANSWER
If you have many options, you usually create a seperate table, only with an id and description (or name). To Connect these two tables, you insert a field into the CHECKLIST_ANSWER-Table, and define it as a foreign key, which references to the id (primary key) of the new table, I have mentioned first.
Hope it is clear :)
I don't see any problem with adding the new column to your existing table. I would include a check constraint that required that either TOGGLE_VALUE or QUANTITY_VALUE be null (but not both).
There's no good reason to create a second, nearly identical table, where only a single column varies. In my experience, that tends to lead to more problems than the single-table solution (it's practically an invitation to use dynamic SQL).
I definitely would not re-use the existing column (as suggested in another answer), as that would prevent the use of a foreign key on the toggle value.
If I understand your question correctly you're looking for advice on how to store the new type of answers in your schema?
Since this is a new type of answer you'd need to denote that the format of the data is now different from your y/n/na answer type. You could do this by adding another table CheckListAnswerType and a FK in your CHECKLIST_ANSWER table.
However, your CHECKLIST_INSTANCE_ID could easily indicate that this is a type of checklist that follows a certain answer pattern. I'm not sure about the rest of your schema buy you could have a CHECKLIST_INSTANCE table that specifies it's answer type...
Your TOGGLE_VALUE could follow a numeric scheme for your new answer types and with the a fore mentioned CheckListAnswerType you could and would have to always take this into account when querying the data to make sure you weren't picking the wrong answer type given the question context so that you didn't get a Yes value while looking for your How many incorrect dimensions were found on the drawing? answer.
I would think all of that would be fine, UNTIL you start wanting to store answers of a different data-type. Then it would be time to redesign schema.
TL;DR: If you're using the same data-type for answers then you would be okay re-using the existing schema (column) while adding a way to tell the answer, or question/answer, types apart to query accurately. If you want to store other data-types in TOGGLE_VALUE, implement new schema objects to do so. Don't try and force other data-types into the current schema if you can avoid it. Also if you did this consider renaming TOGGLE_VALUE as it no longer represents a Toggle. answerValue might better fit the new design.