我们有一个问答表。表格和内容如下,每位用户保留答案。
Answer table:
FKQID Answ UserID
1 Y 1
2 Y 2
Question table:
ID Question
1 Do you agree to x and y?
2 Do you agree to x, y and z?
我们想要更改问题但我们无法更改现有行的问题,因为我们无法保留有关哪些用户在此问题之前回答问题的历史数据#39;改变了。我们有一个存储过程,用于返回用户提供的问题及其答案:
CREATE PROCEDURE spGetUserQuestionAndAnswers
@UserID int
AS
BEGIN
DECLARE @temp Table
(
QID int,
Question nvarchar(200),
Answer nvarchar(200)
)
INSERT INTO @temp
SELECT * FROM
(
Select q.ID as QID,
Ques,
(
SELECT Answ FROM Answer
WHERE Answer.UserID = @UserID
AND q.ID = FKQID
) As Ans
FROM Question q
) qq
--WHERE 1 = CASE WHEN QID = 1 AND Ans IS NULL THEN 0 ELSE 1 END --Can't use this 'cos too slow
--If I filter @temp with the where clause above then I can do something like
--this below but it slows down the above query too much
--DECLARE @1WasAnsweredBefore
--SET @1WasAnsweredBefore = CAST(SELECT COUNT(*) FROM @temp WHERE QID = 1 AS bit)
--SELECT * FROM @temp t
--WHERE 1 = CASE WHEN QID = 2 AND @1WasAnsweredBefore THEN 0 ELSE 1 END
SELECT * FROM @temp t
WHERE 1 = CASE WHEN QID = 1 AND t.Answer IS NULL THEN 0 ELSE 1 END
--AND IF @temp has QID = 1, THEN Exclude QID = 2 ????
END
这将返回用户的问题和答案。如果用户第一次回答问题,则答案为NULL,这很好。
我需要做的是如果用户之前没有回答QID = 1(Ans IS NULL)然后向用户显示Q 2,我在最后一个WHERE中过滤掉了。我不能做的是,如果结果集包含Q 1,意味着它之前被用户回答,然后过滤掉Q 2. SP中的注释掉的行就是我尝试但是如果我把WHERE过滤器放在执行插入的SELECT,然后查询太慢。我能想到的另一个解决方案是在@temp上运行过滤器,从@temp执行另一次插入到@ temp2并在@temp中存在Q 1时排除Q 2但是感觉有点太多了,那可能是一个没有使用2个临时表的解决方案。
那么如果结果集包含Q 1,如何从结果集中排除Q 2?
编辑:我在上面提供了示例数据,这些数据足以说明问题。
致电
exec spGetUserQuestionAndAnswers 2
返回
QID Question Answer
2 Do you agree to x, y and z? Y
这很好。用户2之前未回答Q 1,因此SP过滤掉Q1并返回Q2
致电
exec spGetUserQuestionAndAnswers 1
返回
QID Question Answer
1 Do you agree to x and y? Y
2 Do you agree to x, y and z? NULL
这不好,它不应该包括Q2,因为用户之前已经回答了问题1。
答案 0 :(得分:0)
这就是我解决这个问题的方法,但是如果你有一个不使用@ temp2的解决方案,或者更简单的解决方案,请告诉我。
ALTER PROCEDURE spGetUserQuestionAndAnswers
@UserID int
AS
BEGIN
DECLARE @temp Table
(
QID int,
Question nvarchar(200),
Answer nvarchar(200)
)
INSERT INTO @temp
SELECT * FROM
(
Select q.ID as QID,
Ques,
(
SELECT Answ FROM Answer
WHERE Answer.UserID = @UserID
AND q.ID = FKQID
) As Ans
FROM Question q
) qq
DECLARE @temp2 Table
(
QID int,
Question nvarchar(200),
Answer nvarchar(200)
)
Declare @Q1Exists bit
SELECT @Q1Exists = CAST((SELECT Count(*)
FROM @temp
WHERE QID = 1 AND Answer IS NOT NULL) as bit)
insert into @temp2
SELECT * FROM @temp t
WHERE 1 = CASE WHEN QID = 1 AND t.Answer IS NULL THEN 0
ELSE 1 END
SELECT * FROM @temp2
WHERE 1 = CASE WHEN QID = 2 THEN ~@Q1Exists
ELSE 1 END
END
答案 1 :(得分:0)
select max(ID)
from question
left join answer
on answer.FKQID = question.ID
and answer.Answ <> null
and answer.UserID = @UserID
where answer.FKQID is null