在单个MySql存储过程中按多列分组

时间:2018-11-01 07:48:48

标签: mysql stored-procedures

我具有以下存储过程,可用于在多个ASP图表项目上显示数据。

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetChartApprovedData`(in siteValue varchar(45),
in skillValue varchar(100), in shiftValue varchar(100), in tmValue varchar(45), 
in grpmValue varchar(45), in dateValue date, in dateValue1 date)
BEGIN
SELECT count(agentlogin) AS totalApproved, shift AS Shift, skill AS Skill, tm AS TM, grpM AS GrpM
   FROM approved
   WHERE (sitevalue IS NULL
           OR site = sitevalue)
         AND (skillvalue IS NULL
               OR skill = skillvalue)
         AND (shiftvalue IS NULL
               OR shift = shiftvalue)
         AND (tmValue IS NULL
                OR tm = tmValue)
         AND (grpmValue IS NULL
                OR grpM = grpmValue)
         AND (dateValue IS NULL
                OR date BETWEEN dateValue AND dateValue1)
                group by shift, skill;
END

当我使用以上存储过程在ASP图表中显示数据时,我得到以下结果

enter image description here

两个图表都给出相同的分组结果。我想要的是第一个图表,我希望它按班次分组,而第二个图表,我希望它按技能分组。是否可以在不使用单独的存储过程的情况下实现这两者?请告诉我。在此先感谢:)

private void GetChartData()
{
    string MyConString = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
    MySqlConnection con = new MySqlConnection(MyConString);
    MySqlCommand cmd = new MySqlCommand("GetChartApprovedData");
    cmd.CommandType = CommandType.StoredProcedure;
    string siteValue = null;
    DateTime? dateValue = null;
    DateTime? dateValue1 = null;
    if (ddlSite.SelectedValue != null && ddlSite.SelectedValue != "0")
    {
       siteValue = ddlSite.SelectedValue;
    }
    if (ViewState["Date"] != null && ViewState["Date"].ToString() != "0")
    {
        dateValue = DateTime.Parse(ViewState["Date"].ToString());
    }
    if (ViewState["Date1"] != null && ViewState["Date1"].ToString() != "0")
    {
        dateValue1 = DateTime.Parse(ViewState["Date1"].ToString());
    }
    cmd.Parameters.AddWithValue("siteValue", siteValue);
    cmd.Parameters.AddWithValue("dateValue", dateValue);
    cmd.Parameters.AddWithValue("dateValue1", dateValue1);
    cmd.Connection = con;
    con.Open();
    MySqlDataReader myread = cmd.ExecuteReader();
    while (myread.Read())
    {
        this.Chart2.Series["Series1"].Points.AddXY(myread["Shift"], myread["totalApproved"]);
        Chart2.Series["Series1"].IsValueShownAsLabel = true;
        Chart2.Series["Series1"].Label = "#VALY(#PERCENT)";
        Chart2.Series["Series1"].ToolTip = "Shift: #VALX \\nCount: #VALY";
        Chart2.ChartAreas["ChartArea1"].AxisX.LabelStyle.Interval = 1;
        Chart2.Legends.Clear();
        Chart2.ChartAreas["ChartArea1"].AxisX.MajorGrid.Enabled = false;
        Chart2.ChartAreas["ChartArea1"].AxisY.MajorGrid.Enabled = false;
        Chart2.Series["Series1"].Color = Color.DarkOrange;


        this.Chart1.Series["Series1"].Points.AddXY(myread["Skill"], myread["totalApproved"]);
        Chart1.Series["Series1"].IsValueShownAsLabel = true;
        Chart1.Series["Series1"].Label = "#VALY(#PERCENT)";
        Chart1.Series["Series1"].ToolTip = "Skill: #VALX \\nCount: #VALY";
        Chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Interval = 1;
        Chart1.Series["Series1"].Color = Color.DarkOrange;
        Chart1.Series["Series1"].LabelBackColor = Color.White;
        Chart1.Legends.Clear();
        Chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.Enabled = false;
        Chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.Enabled = false;
   }
   con.Close();
}

3 个答案:

答案 0 :(得分:3)

是的,可以使用Dynamic SQL。我们可以创建一个查询字符串,然后准备并执行它。这将使我们能够指定动态列名,而这是直接不可能的。

您还需要使用另一个参数来指定要在Group By中使用哪一列

DELIMITER $$

CREATE DEFINER=`root`@`localhost` 
  PROCEDURE `GetChartApprovedData`(in siteValue varchar(45),
                                   in skillValue varchar(100), 
                                   in shiftValue varchar(100), 
                                   in tmValue varchar(45), 
                                   in grpmValue varchar(45), 
                                   in dateValue date, 
                                   in dateValue1 date, 
                                   in groupByColumn varchar(64)) 
-- add extra in parameter, groupByColumn, to specify which column to group upon 

BEGIN

SET query_str = CONCAT('SELECT 
                          count(agentlogin) AS totalApproved, 
                          shift AS Shift, 
                          skill AS Skill, 
                          tm AS TM, 
                          grpM AS GrpM
                        FROM approved
                        WHERE (sitevalue IS NULL
                               OR site = sitevalue)
                          AND (skillvalue IS NULL
                               OR skill = skillvalue)
                          AND (shiftvalue IS NULL
                               OR shift = shiftvalue)
                          AND (tmValue IS NULL
                               OR tm = tmValue)
                          AND (grpmValue IS NULL
                               OR grpM = grpmValue)
                          AND (dateValue IS NULL
                               OR date BETWEEN dateValue AND dateValue1)
                        GROUP BY ', 
                        groupByColumn); -- concatenate the group by column param

-- prepare the query
PREPARE stmt FROM query_str;

-- execute the query
EXECUTE stmt;

-- Clear up
DEALLOCATE PREPARE stmt;

END $$

DELIMITER ;

答案 1 :(得分:1)

解决问题的一种方法是在过程内进行两个查询(一个向 <?xml version="1.0" encoding="UTF-8"?> <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:for-each select="Tests/Test"> <xsl:if test="@TestType='CMD'"> <xsl:value-of select="current()"> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet 转移,一个向GROUP BY转移技能,并在结果中使用标记指示结果是否为按班次或技能分组的数据:

GROUP BY

然后在您的C#代码中,您将更改以下行:

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetChartApprovedData`(in siteValue varchar(45),
in skillValue varchar(100), in shiftValue varchar(100), in tmValue varchar(45), 
in grpmValue varchar(45), in dateValue date, in dateValue1 date)
BEGIN
SELECT 'skill' AS type, count(agentlogin) AS totalApproved, skill AS Skill, tm AS TM, grpM AS GrpM
   FROM approved
   WHERE (sitevalue IS NULL
           OR site = sitevalue)
         AND (skillvalue IS NULL
               OR skill = skillvalue)
         AND (shiftvalue IS NULL
               OR shift = shiftvalue)
         AND (tmValue IS NULL
                OR tm = tmValue)
         AND (grpmValue IS NULL
                OR grpM = grpmValue)
         AND (dateValue IS NULL
                OR date BETWEEN dateValue AND dateValue1)
                group by skill;
SELECT 'shift' AS type, count(agentlogin) AS totalApproved, shift AS Shift, tm AS TM, grpM AS GrpM
   FROM approved
   WHERE (sitevalue IS NULL
           OR site = sitevalue)
         AND (skillvalue IS NULL
               OR skill = skillvalue)
         AND (shiftvalue IS NULL
               OR shift = shiftvalue)
         AND (tmValue IS NULL
                OR tm = tmValue)
         AND (grpmValue IS NULL
                OR grpM = grpmValue)
         AND (dateValue IS NULL
                OR date BETWEEN dateValue AND dateValue1)
                group by shift;
END

收件人:

    this.Chart2.Series["Series1"].Points.AddXY(myread["Shift"], myread["totalApproved"]);
    this.Chart1.Series["Series1"].Points.AddXY(myread["Skill"], myread["totalApproved"]);

答案 2 :(得分:0)

如果您只想重用c#代码大小,则可以使用Madhu Bhaiya提供的存储过程以及下面的代码来获得所需的结果:

    private void GetChartData()
    {
        string MyConString = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
        MySqlConnection con = new MySqlConnection(MyConString);


        //PTK: TypeOfChartValue should be change with chart type you are using (I did not know what chart library you are using in your code
        Dictionary<string, TypeOfChartValue> charts = new Dictionary<string, Chart>()
        {
            { "shift", this.Chart2 },  //PTK: the first value here is a column name to use in group by , the second is the chart to fill with resulted data. this line means that the Chart2 must be filled with data grouped by  'shift'
            { "skill", this.Chart1 }  //PTK: the first value here is a column name to use in group by , the second is the chart to fill with resulted data. this line means that the Chart1 must be filled with data grouped by  'skill'
            //PTK: you can add here as many charts as you wish
        };
        foreach (string groupby in charts.Keys)
        {
            //PTK: TypeOfChartValue should be change with chart type you are using (I did not know what chart library you are using in your code
            TypeOfChartValue chart = charts[groupby];

            MySqlCommand cmd = new MySqlCommand("GetChartApprovedData");
            cmd.CommandType = CommandType.StoredProcedure;
            string siteValue = null;
            DateTime? dateValue = null;
            DateTime? dateValue1 = null;
            if (ddlSite.SelectedValue != null && ddlSite.SelectedValue != "0")
            {
                siteValue = ddlSite.SelectedValue;
            }
            if (ViewState["Date"] != null && ViewState["Date"].ToString() != "0")
            {
                dateValue = DateTime.Parse(ViewState["Date"].ToString());
            }
            if (ViewState["Date1"] != null && ViewState["Date1"].ToString() != "0")
            {
                dateValue1 = DateTime.Parse(ViewState["Date1"].ToString());
            }
            cmd.Parameters.AddWithValue("siteValue", siteValue);
            cmd.Parameters.AddWithValue("dateValue", dateValue);
            cmd.Parameters.AddWithValue("groupByColumn", groupby);

            cmd.Connection = con;
            con.Open();
            MySqlDataReader myread = cmd.ExecuteReader();
            while (myread.Read())
            {
                chart.Series["Series1"].Points.AddXY(myread["Shift"], myread["totalApproved"]);
                chart.Series["Series1"].IsValueShownAsLabel = true;
                chart.Series["Series1"].Label = "#VALY(#PERCENT)";
                chart.Series["Series1"].ToolTip = "Shift: #VALX \\nCount: #VALY";
                chart.ChartAreas["ChartArea1"].AxisX.LabelStyle.Interval = 1;
                chart.Legends.Clear();
                chart.ChartAreas["ChartArea1"].AxisX.MajorGrid.Enabled = false;
                chart.ChartAreas["ChartArea1"].AxisY.MajorGrid.Enabled = false;
                chart.Series["Series1"].Color = Color.DarkOrange;

            }
            con.Close();
        }
    }