Группировка по нескольким столбцам в одной хранимой процедуре MySql - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть хранимая ниже процедура, которую я использую для отображения данных по нескольким элементам диаграммы 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 голосов
/ 18 ноября 2018

Если вы просто хотите уменьшить размер кода 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();
        }
    }
0 голосов
/ 20 ноября 2018

Одним из способов решения этой проблемы было бы выполнение обоих запросов внутри вашей процедуры (от одного до GROUP BY смещения и от одного до GROUP BY скилла) и использование флага в результатах, чтобы указать, были ли результаты сгруппированы по смещению. или умение:

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

Тогда в вашем коде c # вы изменили бы эти строки:

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

до:

if (myread["Type"] == "shift") {
     this.Chart2.Series["Series1"].Points.AddXY(myread["Shift"], myread["totalApproved"]);
}
if (myread["Type"] == "skill") {
     this.Chart1.Series["Series1"].Points.AddXY(myread["Skill"], myread["totalApproved"]);
}
0 голосов
/ 01 ноября 2018

Да, это возможно при использовании Динамический 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 ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...