简体   繁体   中英

T-SQL - Is there a way that I can dynamically output columns based on the number of rows for a specified value in a table?

The database I am working with is a Microsoft SQL Server database. In this database, I have a table of questionnaires and a table of questions. The values in the table column called questionnaire_id is a primary key on the questionnaire table and a foreign key on the question table. Each questionnaire can consist of any number of questions. I also have a person table and an answer table. The question_id, which is the primary key on the question table, and the person_id, which is the primary key on the person table, are both foreign keys on the answer table.

My goal is to write a query that can be reused for any current or future questionnaire. The output would consist of one row per person and would include some columns from the person table as well as one column per question and one column per answer. This is simple if I know how many questions are on each questionnaire, but in this case I do not.

Ideally, I want to only have to specify the name of the questionnaire for which I would like to generate the report, without having to alter the query in any other way. Does anyone have any idea how I can do this?

  1. You will have to select the persons taking part in the requested questionnaire. Because the persons are linked to the answers and the answers are linked to the questions and the questions are linked to the requested questionnaire you will need all tables to do this. You will also need to use a DISTINCT clause because a person is linked to many answers.
  2. You have to select all the question_id's of the questions linked to the requested questionnaire
  3. For each question and each person you will now have to create a subselect for a column from the questions table and another subselect for a column from the answers table.

This has to be done by creating the SQL statement dynamically. See this example:

DECLARE @questionnaire INT
DECLARE @qa VARCHAR(MAX)
DECLARE @Sql AS VARCHAR(MAX)

SET @questionnaire = 1
SELECT  @qa = COALESCE(@qa,'')  + 
'
, (select q.text 
from t_answer a
join t_question q
    on q.question_id = a.question_id
where q.question_id=' + CAST(q.question_id AS VARCHAR(10)) + '
and a.person_id = p.person_id) as question'+  CAST(q.question_id AS VARCHAR(10)) +
'
, (select a.text 
from t_answer a
where a.question_id=' + CAST(q.question_id AS VARCHAR(10)) + '
and a.person_id = p.person_id) as answer'+  CAST(q.question_id AS VARCHAR(10)) 

FROM t_question q
WHERE q.questionnair_id=@questionnaire

SET @sql = 'select distinct p.name ' + @qa + '
from t_person p
join t_answer a
    on a.person_id = p.person_id
join t_question q
    on q.question_id = a.question_id
join t_questionnaire r
    on r.questionnair_id = q.questionnair_id
where r.questionnair_id=' + CAST(@questionnaire AS VARCHAR(10))

PRINT @sql

--EXECUTE (@sql)

You will have to change the table and field names but this should do the job.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM