根据总行数选择问题

时间:2019-04-06 23:46:42

标签: c# asp.net sql-server

所以,我是C#和asp.net的初学者(实际上是整个编程:$) ,我想做一个简单的试卷生成器 ,但我有一些问题。

我有表格“问题”


    [level]       INT    
    [subjectId]   VARCHAR 
    [subjectname] VARCHAR
    [question]    VARCHAR
    [answer]      VARCHAR
    [difficulty]  CHAR 
    [mark]        INT      

具有不同主题,级别和标记的许多问题..etc 所以我希望用户选择级别,subId,难度和总分。 在我的代码中 它根据选定的条件(总分除外)生成问题,并在gridview中将其与每个问题的分值一起显示,并且工作正常。 我不能做的是总标记部分,我希望它仅选择一个问题,即其标记的总和等于用户选择的值

我可以选择总分

<asp:RadioButtonList ID="total" runat="server">
            <asp:ListItem Value="10">10</asp:ListItem>
            <asp:ListItem Value="15">15</asp:ListItem>
            <asp:ListItem Value="40">40</asp:ListItem>
        </asp:RadioButtonList>

所以我希望当用户选择例如10时,它将选择5个2标记的问题,或任何其标记总和等于10的问题。

我尝试了很多方法。我用

// with group by and w/o the where condition 
" having SUM(mark) = "+total.SelectedValue+ " "

但是我错误地(没有主键)将行重复了5次(没有主键),数据库将其视为一行(带有2个标记的问题) 因此,该句子仅选择了该行,

我什至不知道如何一起使用“ where”和“ having”-> //这部分解决了 但它仍只显示重复的记录,而DISTINCT不显示任何内容

但是我想选择带有不同标记的不同行(不同问题) 但我不知道

那么,是否可以在我的代码中加上这个条件?如果没有,我可以用其他方式编写代码吗?

con.Open();
        SqlDataAdapter sda;
                if (dif.SelectedValue == "easy")
                {

                    sda = new SqlDataAdapter("Select subjectId, level, difficulty, question, mark from addquestion where subjectId= '" + sudjectID.SelectedValue + "' and level= " + level.SelectedValue + " and difficulty = '" + dif.SelectedValue + "' ORDER BY NEWID() ", con);
                }
                else if (dif.SelectedValue == "medium")
                {

                    sda = new SqlDataAdapter("Select subjectId, level, difficulty, question, mark from addquestion where subjectId= '" + sudjectID.SelectedValue + "' and level= " + level.SelectedValue + " and difficulty = '" + dif.SelectedValue + "' ORDER BY NEWID() ", con);
                }
                else if (dif.SelectedValue == "hard")
                {

                    sda = new SqlDataAdapter("Select subjectId, level, difficulty, question, mark from addquestion where subjectId= '" + sudjectID.SelectedValue + "' and level= " + level.SelectedValue + " and difficulty = '" + dif.SelectedValue + "' ORDER BY NEWID() ", con);
                }
                else
                    sda = new SqlDataAdapter("Select subjectId, level, difficulty, question, mark from addquestion where subjectId='" + sudjectID.SelectedValue + "' and level=" + level.SelectedValue + " ORDER BY NEWID() ", con);

        sda.SelectCommand.ExecuteScalar();
        DataTable dt = new DataTable();
                sda.Fill(dt);
                GridView1.DataSource = dt;
                GridView1.DataBind();

                con.Close();

我实际上已经以多种方式尝试了很多事情,并且我几乎已经阅读了Internet:'),并观看了所有YT:'),但是我找不到任何解决方案。  甚至我都希望找到我不理解的复杂事物,但会问如何做,但我没有:') 所以非常感谢能帮助<3

的人

这是我的生成页面(如果有帮助的话)

    <asp:Label ID="Label3" runat="server" Text="Subject ID"></asp:Label>
        <br />
        <asp:DropDownList ID="sudjectID" runat="server">
            <asp:ListItem></asp:ListItem>
            <asp:ListItem>CSC-101</asp:ListItem>
            <asp:ListItem>3-COMP-011</asp:ListItem>
            <asp:ListItem>COMP3-112</asp:ListItem>
            <asp:ListItem>COMP-151</asp:ListItem>
            <asp:ListItem>COMP-213</asp:ListItem>
            <asp:ListItem>INFS-241</asp:ListItem>
            <asp:ListItem>COMP-003</asp:ListItem>
            <asp:ListItem>COMP-336</asp:ListItem>
            <asp:ListItem>COMP-004</asp:ListItem>
            <asp:ListItem>COMP-433</asp:ListItem>
        </asp:DropDownList>
         <br />
        <br />
        <asp:Label ID="Label2" runat="server" Text="Level"></asp:Label>
        <br />
        <asp:DropDownList ID="level" runat="server">
                <asp:ListItem></asp:ListItem>
                <asp:ListItem>1</asp:ListItem>
                <asp:ListItem>2</asp:ListItem>
                <asp:ListItem>3</asp:ListItem>
                <asp:ListItem>4</asp:ListItem>
                <asp:ListItem>5</asp:ListItem>
                <asp:ListItem>6</asp:ListItem>
                <asp:ListItem>7</asp:ListItem>
                <asp:ListItem>8</asp:ListItem>
                <asp:ListItem>9</asp:ListItem>
                <asp:ListItem>10</asp:ListItem>
            </asp:DropDownList>            <br />
        <br />
        <asp:Label ID="Label1" runat="server" Text="Difficulty"></asp:Label>
        <br />
        <asp:RadioButtonList ID="dif" runat="server">
            <asp:ListItem>easy</asp:ListItem>
            <asp:ListItem>medium</asp:ListItem>
            <asp:ListItem>hard</asp:ListItem>
            <asp:ListItem>random</asp:ListItem>
        </asp:RadioButtonList>
        <br />
        <asp:Label ID="Label4" runat="server" Text="Total Mark"></asp:Label>
        <asp:RadioButtonList ID="total" runat="server">
            <asp:ListItem Value="10">10</asp:ListItem>
            <asp:ListItem Value="15">15</asp:ListItem>
            <asp:ListItem Value="40">40</asp:ListItem>
        </asp:RadioButtonList>
        <br />
        <asp:Button ID="Button1" runat="server" Height="35px" OnClick="Button1_Click" Text="Generate" Width="92px" />
         <br />
         <asp:GridView ID="GridView1" runat="server">
        </asp:GridView>

2 个答案:

答案 0 :(得分:1)

您的问题有太多疑问,让我澄清其中一个..然后再解决其余问题。

  

//,我什至不知道如何使用“ where”和“ having”   一起//

Where子句用于过滤大型数据集。

具有用于过滤分组数据。基本上与Group By子句一起使用。

在此示例中,我要查询筛选分数> 2的问题,然后将分数分组并显示所有包含至少3个问题的分数。

选择得分,将Count()作为得分的问题,取自FROM得分> 2按得分分组的得分的问题()> = 3

答案 1 :(得分:0)

此部分

  

,我什至不知道如何使用“ where”和“ having”   一起

这是一个简单的syantax:

SELECT columns, aggratiotion functions (e.g. SUM, COUNT ..etc)
FROM tableName
WHERE 
    column = value 
GROUP BY columns 
HAVING 
 (aggratiotion functions) = value 

示例:

SELECT 
    subjectId
,   level
,   difficulty
,   question
,   SUM(mark) 
FROM 
    addquestion 
WHERE 
    subjectId   = somevalue
AND level       = somevalue
AND difficulty  = somevalue
GROUP BY 
    subjectId
,   level
,   difficulty
,   question
HAVING 
    SUM(mark) = somevalue

对于C#部分,您正在使自己复杂化。给自己一个休息时间,然后忘记它,这将帮助您获得更多的关注,并在您每次重新尝试时都更加清晰的想法。

对于初学者,您只需将查询调整为:

"SELECT DISTINCT subjectId, level, difficulty, question, SUM(mark) FROM addquestion WHERE subjectId = '" + sudjectID.SelectedValue + "' AND level = " + level.SelectedValue + " AND difficulty = '" + dif.SelectedValue + "' GROUP BY subjectId, level, difficulty, question HAVING SUM(mark) = " + total.SelectedValue + " ORDER BY NEWID()";

相同的原则。额外的DISTINCT将避免重复。

尽管,建议使用参数化查询,但我不想让情况更糟;)。只要您正在学习,就应该将注意力集中在所学的内容上,并及时掌握这部分内容。

这是代码中的示例(未经测试,仅用于演示目的)。

string query = string.Empty;

string[] difficulties = {"easy", "medium", "hard"};

if(!difficulties.Contains(dif.SelectedValue))
{ 
    query = string.Format("SELECT DISTINCT subjectId, level, difficulty, question, SUM(mark) FROM addquestion WHERE subjectId = '{0}' AND level = {1} GROUP BY subjectId, level, question HAVING SUM(mark) = {2} ORDER BY NEWID()", sudjectID.SelectedValue, level.SelectedValue, total.SelectedValue); 
}       
else
{
    query = string.Format("SELECT DISTINCT subjectId, level, difficulty, question, SUM(mark) FROM addquestion WHERE subjectId = '{0}' AND level = {1} AND difficulty = '{2}' GROUP BY subjectId, level, difficulty, question HAVING SUM(mark) = {3} ORDER BY NEWID()", sudjectID.SelectedValue, level.SelectedValue, dif.SelectedValue, total.SelectedValue); 
}       


var dataTable = new DataTable(); 

using(SqlConnection con = new SqlConnection(ConnectionString))
using(SqlCommand command =  new SqlCommand(query, con))
using(SqlDataAdapter adapter = new SqlDataAdapter(command))
{
    con.Open();
    adapter.Fill(dataTable);
}

GridView1.DataSource = dataTable;
GridView1.DataBind();

选择项下的任何内容,都会显示给用户,例如,如果要隐藏SUM(mark),只需将其从选择项中删除即可。

更新

    if (!difficulties.Contains(dif.SelectedValue.ToLower()))
    {

        query = string.Format("SELECT subjectId, level, difficulty, question FROM (SELECT *, SUM(mark) OVER(PARTITION BY subjectId ORDER BY subjectId ROWS UNBOUNDED PRECEDING) TotalMark FROM addquestion) d WHERE subjectId = '{0}' AND level = {1} AND TotalMark <= {2}", sudjectID.SelectedValue.ToString().Trim().ToLower(), level.SelectedValue, total.SelectedValue);
    }
    else
    {
        query = string.Format("SELECT subjectId, level, difficulty, question FROM (SELECT *, SUM(mark) OVER(PARTITION BY subjectId, difficulty ORDER BY subjectId ROWS UNBOUNDED PRECEDING) TotalMark FROM addquestion) d  WHERE subjectId = '{0}' AND level = {1} AND TotalMark <= {2} AND difficulty = '{3}'", sudjectID.SelectedValue.ToString().Trim().ToLower(), level.SelectedValue,total.SelectedValue, dif.SelectedValue.ToString().Trim().ToLower());
    }