Разделить список по сгруппированным данным - PullRequest
0 голосов
/ 13 сентября 2018

У меня есть список записей продуктов, которые я отображаю в таблице данных, сгруппированных по названию / идентификатору отдела. Из изображения ниже мои возвращенные данные не включают выделенные строки . Я пытаюсь добиться того, что показано на рисунке: для каждого набора продуктов, уже сгруппированных по отделам (пустыня, канцтовары, домашнее хозяйство), получим итоги и название отдела (и другие столбцы, которые я удалил, чтобы показать меньше беспорядка), чтобы добавить в список

enter image description here

Я пытаюсь достичь результата выше

Это мой текущий код / ​​запрос, который возвращает эти данные без выделенных строк

List<SaleDetailViewModel> list = new List<SaleDetailViewModel>();

NpgsqlCommand query = new NpgsqlCommand
     ("SELECT  q_department.q_name, q_saledetail.q_code, q_saledetail.q_description, " +
     "SUM(q_quantity) AS qtysum,  " + //running total of q_quantity for the product in that department     
     "FROM q_saledetail " +                    
     "LEFT JOIN q_department ON (q_saledetail.q_departmentid = q_department.q_code ) " +     
     "GROUP BY " +
     "q_saledetail.q_departmentid, q_department.q_name, q_saledetail.q_description, q_saledetail.q_code " +
     "ORDER BY q_saledetail.q_departmentid "
     , connectToDB);

NpgsqlDataReader read = query.ExecuteReader();

while(read.Read())
{
     var reportData = new SaleDetailViewModel();

     reportData.departmentName = read["q_name"].ToString(); //department name
     reportData.q_description = read["q_description"].ToString(); //product DESCRIPTION
     reportData.q_code = read["q_code"].ToString(); //product BAR CODE
     reportData.sumOfQuantity = Convert.ToDecimal(read["qtysum"]); //sum of quantity sold for that product


     list.Add(reportData);
}

connectToDB.Close();
return list;

Теперь моя задача - добавить сгруппированные данные строки отдела для каждого набора продуктов и добавить к списку, который будет возвращен, т.е.

//--
foreach(grouped dataset by department)
{
     //get the totals and heading for each set of data
     reportData.q_code = //insert department id
     reportData.q_description = //insert department name
     reportData.sumOfQuantity = // insert total for that department

     list.Add(reportData) //add that to the list that will be shown on view
}
//--

Я могу получить идентификатор отдела и код для сгруппированных данных, используя read.GetString ().

string deptName = read.GetString(0);

Как мне продолжить циклически просматривать dataReader и добавлять итоги для каждого общего набора, такого как столбцы количества, и добавлять его в качестве отдельной строки для добавления в список? ... чтобы получить результат из показанного изображения .

Попытка объяснить немного лучше: В моем цикле while я собираю набор для каждой группы продуктов отдела и создаю строку для добавления в список. Или есть лучший способ добиться этого ..

1 Ответ

0 голосов
/ 07 ноября 2018

Вариант 1 : Sql и союз.

 SELECT  
    q_department.q_name,
    q_saledetail.q_code, 
    q_saledetail.q_description, 
     SUM(q_quantity) AS qtysum, --running total of q_quantity for the product in that department     
     FROM q_saledetail 
     LEFT JOIN q_department ON (q_saledetail.q_departmentid = q_department.q_code ) 
     GROUP BY 
     q_saledetail.q_departmentid, q_department.q_name, q_saledetail.q_description, q_saledetail.q_code


 UNION

 SELECT 
    q_department.q_name,
    '',
    '',
    sum(q_quantity)
    FROM q_saledetail 
     LEFT JOIN q_department ON (q_saledetail.q_departmentid = q_department.q_code ) 
    GROUP BY 
     q_saledetail.q_departmentid, q_department.q_name

     ORDER BY q_saledetail.q_departmentid 

Путем удаления некоторых полей, которые идентифицируют различные q_saledetail из списка group by, функция суммы будет суммировать все отделы вместо того, чтобы разбивать суммы.

Извинитено я не могу точно вспомнить, как упорядочивание работает с операторами объединения, но я знаю, что вы можете упорядочить только в одном месте, либо в последнем, либо в первом, либо с помощью внешнего запроса, который выбирает из объединения.

То, что вы теперь будете иметь в своих данных, это строки, которые являются «общими» строками для каждого отдела, которые, как вы знаете, являются «общими» строками, потому что поля q_code или q_description пусты.Затем можно упорядочить набор данных по отделам, а затем по коду (asc или desc), чтобы пустое поле кода находилось в конце группы этого отдела, и отображать его следующим образом.

Опция2 : работает Linq и небольшой ручной код

List<SaleDetailViewModel> list = new List<SaleDetailViewModel>();

while(read.Read())
{
    ... //Your mapping code
     list.Add(reportData);
}
var groupedList = list.GroupBy(x => x.departmentName);

, который даст вам IEnumerable<IGrouping<string, SaleDetailViewModel>.

Что это ваши данные, теперь сгруппированные по названию каждого отделакоторый действует как ключ. Теперь вы перебираете groupedList и добавляете значения этого IGrouping up.

foreach(var group in groupedList)
{
    var total = 0;
    foreach(var saledetail in group)
    {
        total += saledetail.sumOfQuantity;
    }


}

Затем вам просто нужно добавить логику, чтобы добавить ее в список / вашдатируются в порядке следования этих групп.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...