使用SQL中的连接检索不同的记录

时间:2013-11-12 09:29:26

标签: c# asp.net sql sql-server

我正在使用两个表QuestionInsertQuestion_Papers运行SQL查询。 相关表格中的列如下: -

Table:-QuestionInsert  
Columns:-QuestionNum,Question,Answer,CatId,SubCatId

Table:-Question_Papers  
Columns:-QuestionNum
  1. 我想要一个sql查询,它将从表QuestionInsert中检索所有QuestionNum,Question,Answer,QuestionNum出现在表Question_Papers中。
  2. 另外,我想从表QuestionSesert中检索所有QuestionNum,Question,Answer,在Question_Papers表中没有QuestionNum。
  3. 此数据显示在网格视图上。我使用的查询如下: - 第一个条件的查询是:

    SELECT F.QuestionNum,
           F.Question,
           F.Answer 
    FROM QuestionInsert F 
    INNER JOIN Question_Papers FS ON F.[QuestionNum]=FS.QuestionNum 
    WHERE ((F.QuestionNum=FS.QuestionNum) AND (F.CatId='" + 
    DropDownList1.SelectedValue + "' And F.SubCatId='" + DropDownList3.SelectedValue + "'))  
    ORDER BY F.QuestionNum DESC;
    

    第二个条件的另一个查询。是: -

    SELECT F.QuestionNum,
           F.Question,
           F.Answer 
    FROM QuestionInsert F INNER JOIN Question_Papers FS ON F.[QuestionNum]!=FS.QuestionNum 
    WHERE ((F.QuestionNum!=FS.QuestionNum) AND (F.CatId='" + DropDownList1.SelectedValue + "' 
    And F.SubCatId='" + DropDownList3.SelectedValue + "'))  
    ORDER BY F.QuestionNum DESC
    

    我的代码正在检索正确的信息,但如果QuestionNum表中存在多行Question_Papers,则它会重复显示所有行。我想显示存在的唯一行,而不是单独存在于表Question_Papers中。

    请帮帮我。

3 个答案:

答案 0 :(得分:3)

您可以尝试以下第二个条件:

SELECT F.QuestionNum,F.Question,F.Answer 
FROM QuestionInsert F 
WHERE (F.CatId='" + DropDownList1.SelectedValue + "' And F.SubCatId='" + DropDownList3.SelectedValue + "')
AND F.QuestionNum NOT IN (SELECT QuestionNum FROM Question_Papers)
ORDER BY F.QuestionNum DESC

这是第一个条件:

SELECT F.QuestionNum,F.Question,F.Answer 
FROM QuestionInsert F  
WHERE (F.CatId='" + DropDownList1.SelectedValue + "' 
AND F.SubCatId='" + DropDownList3.SelectedValue + "') 
AND F.QuestionNum IN (SELECT QuestionNum FROM Question_Papers)
ORDER BY F.QuestionNum DESC";

但是,您的代码存在严重问题 - 您是否考虑过SQL injection?有许多数据访问框架,例如Entity Framework,可以帮助您降低更好的路径。

答案 1 :(得分:0)

您可以使用EXISTS

重写您的第一个查询
SELECT F.QuestionNum,F.Question,F.Answer FROM QuestionInsert F 
WHERE EXISTS (SELECT * FROM Question_Papers P WHERE P.QuestionNum = F.QuestionNum)
AND F.CatId='" + DropDownList1.SelectedValue + "' 
AND F.SubCatId='" + DropDownList3.SelectedValue + "'

使用NOT EXISTS

进行第二次查询
SELECT F.QuestionNum,F.Question,F.Answer FROM QuestionInsert F 
WHERE NOT EXISTS (SELECT * FROM Question_Papers P WHERE P.QuestionNum = F.QuestionNum)
AND F.CatId='" + DropDownList1.SelectedValue + "' 
AND F.SubCatId='" + DropDownList3.SelectedValue + "'

请注意,对于这些查询的编写方式(来自您的问题),您很容易受到SQL注入攻击。你应该使用参数。

答案 2 :(得分:0)

似乎没有必要在join中使用where或重复连接子句的理由。形成我可以收集的所有你需要做的是检查是否存在,最新版本(2005+)的sql server支持EXISTS。将此作为单个查询而非相关子查询可用于检查和标记存在

DECLARE @question_insert TABLE ( id INT, question VARCHAR(50), answer VARCHAR(50), catid INT, subcatid INT )
DECLARE @question_paper TABLE ( id INT, question_insert_id INT )

INSERT INTO @question_insert ( id, question, answer, catid, subcatid )
VALUES 
    (1, 'How old are you?', '20', 1, 1),
    (2, 'Who was the first president?', '?', 2, 1)

INSERT INTO @question_paper ( id, question_insert_id )
VALUES (1, 1),(2, 1)

SELECT
    qi.id,
    qi.question,
    qi.answer,
    CASE WHEN EXISTS(SELECT 1 FROM @question_paper qp 
                     WHERE qp.question_insert_id = qi.id) 
         THEN 'Yes' ELSE 'No' END AS in_question_paper
FROM @question_insert qi
--WHERE qi.catid=@catid AND qi.subcatid=@subcatid

demo

或者AS个人查询

SELECT
    qi.id,
    qi.question,
    qi.answer,
    'Yes' AS in_question_paper
FROM @question_insert qi
WHERE EXISTS(SELECT 1 FROM @question_paper qp 
             WHERE qp.question_insert_id = qi.id)

SELECT
    qi.id,
    qi.question,
    qi.answer,
    'No' AS in_question_paper
FROM @question_insert qi
WHERE NOT EXISTS(SELECT 1 FROM @question_paper qp 
                 WHERE qp.question_insert_id = qi.id)

我将重申您应该阅读SQL Injection而不是将用户输入连接到查询中。

还有。 DISTINCT不是“加入中可接受”,而事实并非如此。不可接受的是使用DISTINCT并在查询的另一部分中引用不属于选择列表的列(在这种情况下它将是WHERE子句),这是一种方式这是为了使用GROUP BY代替。