簡體   English   中英

有條件地從兩個表中的一個中選擇值

[英]Conditionally select value from one of two tables

我有一個問卷調查申請表,用戶將提交答案。 有些問題是基於文本的,有些是固定選項。

這些值將作為輸入的文本值或所選選項的Id保存到tAnswers表中。 有一個QuestionTypeId列,用於定義答案是否是對tOptions.Id的引用。

我想選擇答案,返回輸入的值或與所選Id相關的值。

例如;

SET NOCOUNT ON
DECLARE @tSubmissions TABLE (Id INT)
DECLARE @tSubmissionQuestions TABLE (SubmissionId INT, QuestionId INT)
DECLARE @tQuestions TABLE (Id INT, QuestionText NVARCHAR(MAX), ColName NVARCHAR(MAX), QuestionTypeId INT)
DECLARE @tOptions TABLE (Id INT, OptionValue NVARCHAR(MAX), OptionGroupId INT)
DECLARE @tAnswers TABLE (Id INT IDENTITY(1,1), SubmissionId INT, QuestionId INT, AnswerValue NVARCHAR(MAX))

INSERT INTO @tQuestions VALUES (1, 'What is your name?', 'Name', 1)
INSERT INTO @tQuestions VALUES (2, 'What is your age?', 'Age', 1)
INSERT INTO @tQuestions VALUES (3, 'What is your gender?', 'Gender', 2)
INSERT INTO @tQuestions VALUES (4, 'What is your favourite colour?', 'Colour', 2)

-- Answers for question 3 - gender
INSERT INTO @tOptions VALUES (1, 'Male', 1)
INSERT INTO @tOptions VALUES (2, 'Female', 1)

-- answers for question 4 - colour
INSERT INTO @tOptions VALUES (3, 'Blue', 2)
INSERT INTO @tOptions VALUES (4, 'Green', 2)
INSERT INTO @tOptions VALUES (5, 'Red', 2)
INSERT INTO @tOptions VALUES (6, 'Yellow', 2)

INSERT INTO @tSubmissions VALUES (1)
INSERT INTO @tSubmissions VALUES (2)
INSERT INTO @tSubmissions VALUES (3)

INSERT INTO @tSubmissionQuestions VALUES (1, 1)
INSERT INTO @tSubmissionQuestions VALUES (1, 2)
INSERT INTO @tSubmissionQuestions VALUES (1, 3)
INSERT INTO @tSubmissionQuestions VALUES (1, 4)
INSERT INTO @tSubmissionQuestions VALUES (2, 1)
INSERT INTO @tSubmissionQuestions VALUES (2, 2)
INSERT INTO @tSubmissionQuestions VALUES (2, 3)
INSERT INTO @tSubmissionQuestions VALUES (2, 4)
INSERT INTO @tSubmissionQuestions VALUES (3, 1)
INSERT INTO @tSubmissionQuestions VALUES (3, 2)
INSERT INTO @tSubmissionQuestions VALUES (3, 3)
INSERT INTO @tSubmissionQuestions VALUES (3, 4)

-- form submissions
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (1, 1, 'Tony Stark')
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (1, 2, '39')
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (1, 3, '1') -- reference to @tOptions
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (1, 4, '5') -- reference to @tOptions

INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (2, 1, 'Pepper Potts')
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (2, 2, '38')
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (2, 3, '2') -- reference to @tOptions
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (2, 4, '6') -- reference to @tOptions

INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (3, 1, 'James Rhodes')
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (3, 2, '41') -- has choosen to not answer question 3
INSERT INTO @tAnswers (SubmissionId, QuestionId, AnswerValue) VALUES (3, 4, '3') -- reference to @tOptions

SELECT 
    s.Id as SubmissionId, q.Id as QuestionId, a.AnswerValue
FROM 
    @tSubmissions s
INNER JOIN @tSubmissionQuestions sq
    ON sq.SubmissionId = s.Id
INNER JOIN @tQuestions q
    ON q.Id = sq.QuestionId
LEFT JOIN @tAnswers a
    ON a.QuestionId = q.Id
    AND a.SubmissionId = s.Id

DBFiddle

這回來了;

SubmissionId | QuestionId | AnswerValue
=============|============|===============
1            | 1          |  Tony Stark
1            | 2          |  39
1            | 3          |  1     <-- this is the Id of the selected option
1            | 4          |  5     <-- this is the Id of the selected option
2            | 1          |  Pepper Potts
2            | 2          |  38
2            | 3          |  2     <-- this is the Id of the selected option
2            | 4          |  6     <-- this is the Id of the selected option
3            | 1          |  James Rhodes
3            | 2          |  41
3            | 3          |  NULL  <-- the option was not selected
3            | 4          |  3     <-- this is the Id of the option

相反,我想;

SubmissionId | QuestionId | AnswerValue
=============|============|===============
1            | 1          |  Tony Stark
1            | 2          |  39
1            | 3          |  Male    <-- this is the value of the selected option
1            | 4          |  Red     <-- this is the value of the selected option
2            | 1          |  Pepper Potts
2            | 2          |  38
2            | 3          |  Female  <-- this is the value of the selected option
2            | 4          |  Yellow  <-- this is the value of the selected option
3            | 1          |  James Rhodes
3            | 2          |  41
3            | 3          |  NULL    <-- the option was not selected
3            | 4          |  Blue    <-- this is the value of the selected option

如何有條件地從tOptions表中提取值?

我想這就是你要找的東西:另外LETO LEFT JOIN關於tOptions選擇值,在QuestionTypeId = 2情況下,我剛剛添加了ISNUMERIC以避免轉換錯誤。

SELECT 
    s.Id as SubmissionId, 
    q.Id as QuestionId, 
    COALESCE(t.OptionValue,a.AnswerValue) AS AnswerValue
FROM 
    @tSubmissions s
INNER JOIN @tSubmissionQuestions sq
    ON sq.SubmissionId = s.Id
INNER JOIN @tQuestions q
    ON q.Id = sq.QuestionId
LEFT JOIN @tAnswers a
    ON a.QuestionId = q.Id
    AND a.SubmissionId = s.Id
LEFT JOIN @tOptions t
        ON q.QuestionTypeId = 2
       AND ISNUMERIC(a.AnswerValue) = 1
       AND a.AnswerValue = t.Id

請試試這個。

SELECT 
    s.Id as SubmissionId, q.Id as QuestionId,
    CASE WHEN q.QuestionTypeId = 1 THEN 
    a.AnswerValue
    ELSE 
    ISNULL((SELECT  CONVERT(VARCHAR(100),OptionValue) FROM @tOptions o WHERE o.Id = a.AnswerValue),a.AnswerValue)
    END  AS AnswerValue
FROM 
    @tSubmissions s
INNER JOIN @tSubmissionQuestions sq
    ON sq.SubmissionId = s.Id
INNER JOIN @tQuestions q
    ON q.Id = sq.QuestionId
LEFT JOIN @tAnswers a
    ON a.QuestionId = q.Id
    AND a.SubmissionId = s.Id
ORDER BY s.Id ASC

我會在Answers表中創建兩列。 一個你有AnswerValue NVARCHAR(MAX) NULL和另一個AnswerOptionID int NULL 這將使連接方式更有效,並且當引擎嘗試將文本“Tony Stark”轉換為整數時,它將消除問題。

但是,考慮到模式,這里有一個變體。 我將LEFT JOIN添加到@tOptions表中。 請注意,我正在將整數ID轉換為文本,而不是其他方式。

SELECT 
    s.Id as SubmissionId, q.Id as QuestionId
    -- , a.AnswerValue, Options.OptionValue
    ,CASE WHEN q.QuestionTypeId = 2 
        THEN Options.OptionValue 
        ELSE a.AnswerValue 
    END AS AnswerText
FROM 
    @tSubmissions s
    INNER JOIN @tSubmissionQuestions sq ON sq.SubmissionId = s.Id
    INNER JOIN @tQuestions q ON q.Id = sq.QuestionId
    LEFT JOIN @tAnswers a
        ON  a.QuestionId = q.Id
        AND a.SubmissionId = s.Id
    LEFT JOIN @tOptions AS Options
        ON  q.QuestionTypeId = 2
        AND a.AnswerValue = CAST(Options.Id AS NVARCHAR(MAX))
;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM