簡體   English   中英

SQL分組結果,小計和總計

[英]SQL grouping results, sub-total and grand-total

我正在尋找完全堅持的SQL幫助。 還是比較新的...

這是我目前正在做的事情:

private void FillSalesGrid()
    {            
        using (SqlConnection con = new SqlConnection(conn))
        {
            sqlBuilder.Append("SELECT FORMAT(date, 'd', 'en-gb') AS Date, saleID AS [Invoice ID], Patient.firstName + ' ' + Patient.lastName AS [Name], description AS Description,  saleType AS [Type of Sale], saleAmount AS [Amount (R)] FROM Sale LEFT JOIN Patient ON Sale.patientIDNumber = Patient.patientIDNumber WHERE 1=1");

            if (!string.IsNullOrEmpty(comboBox_selectSaleType.Text))
            {
                try
                {
                    sqlBuilder.Append(" AND saleType = @saleType");
                    cParameters.Add(new SqlParameter("@saleType", comboBox_selectSaleType.SelectedItem.ToString()));
                }
                catch
                {
                    MessageBox.Show("no results");
                }
                if (comboBox_selectSaleType.Text == "All Sales")
                {
                    sqlBuilder.Remove(sqlBuilder.Length - 25, 25);
                }
            }

            if (!string.IsNullOrEmpty(datePicker_StartDate.Text) || !string.IsNullOrEmpty(datePicker_EndDate.Text))
            {

                if (!string.IsNullOrEmpty(datePicker_StartDate.Text) && string.IsNullOrEmpty(datePicker_EndDate.Text))
                {
                    sqlBuilder.Append(" AND date > @startDate");
                    cParameters.Add(new SqlParameter("@startDate", datePicker_StartDate.Text));

                }
                else if (string.IsNullOrEmpty(datePicker_StartDate.Text) && !string.IsNullOrEmpty(datePicker_EndDate.Text))
                {
                    sqlBuilder.Append(" AND date < @endDate");

                    cParameters.Add(new SqlParameter("@endDate", datePicker_EndDate.Text));
                }
                else
                {
                    sqlBuilder.Append(" AND date BETWEEN @startDate AND @endDate");
                    cParameters.Add(new SqlParameter("@startDate", datePicker_StartDate.Text));
                    cParameters.Add(new SqlParameter("@endDate", datePicker_EndDate.Text));
                }
            }
            if (!string.IsNullOrEmpty(comboBox_select_Item.Text))
            {
                sqlBuilder.Append(" AND Description LIKE @medName + '%'");
                cParameters.Add(new SqlParameter("@medName", comboBox_select_Item.SelectedItem.ToString()));
            }
            if (!string.IsNullOrEmpty(textBox_PatientIDSelect.Text))
            {
                sqlBuilder.Append(" AND Sale.patientIDNumber = @patientID");
                cParameters.Add(new SqlParameter("@patientID", textBox_PatientIDSelect.Text));
            }

            sqlBuilder.Append(" ORDER BY Sale.date");

            SqlCommand cmd = new SqlCommand(sqlBuilder.ToString(), con);
            if (cParameters.Count != 0)
            {
                cmd.Parameters.AddRange(cParameters.ToArray());
            }

            SqlDataAdapter da = new SqlDataAdapter(cmd);
            dt = new DataTable("Sale");
            da.Fill(dt);
            // totalSales(dt);
            sqlBuilder.Clear();
            cParameters.Clear();
            dataGrid_Reports.ItemsSource = dt.DefaultView;
    }

我正在從“銷售”表中提取數據以獲取銷售報告類型功能。 我正在尋求改進,使其更具可讀性/意義。 如您所見,我正在基於用戶輸入使用參數構建SQL語句。 這可能不是最佳方法。

這是一個示例,顯示了在表單加載時結果如何顯示我的SALES表。

+----------+-------------+-----------+--------------+--------------+--------
|   date   |  Invoice ID |   Name    |  Description |  Sale Type   | Amount 
+--------- +-------------+-----------+--------------+--------------+--------
| 01/02/91 |    1        |   Dean    |   Panado     |  Cash        |  50    
| 02/02/91 |    3        |   Chris   |   Oralox     |  Cash        |  60    
| 03/02/91 |    5        |   Peter   |   Zadin      |  Card        |  99    
| 05/02/91 |    6        |   John    |   Illiadin   |  Medical Aid |  85    
| 08/02/91 |    8        |   Mike    |   Betamine   |  Cash        |  129   
+----------+-------------+-----------+--------------+--------------+--------+

結果將根據輸入的日期,輸入的患者ID,葯品名稱或銷售類型進行“過濾”。

理想情況下,我想要這樣的東西(PatientID鏈接到他們的名字):

Name      InvoiceID    Date         Description   Type of Sale   Amount              
John Doe       1       01/02/2009      Panado        Cash          50
               3       02/02/2009      Panado        Cash          50
               5       03/02/2009      Disprin    Medical Aid      99

Sub-Total                                                         R199

對於每個患者-然后在末尾匯總總計所有小計。

這里的任何幫助將不勝感激。 謝謝。

從問題中假設您的table具有以下示例數據。

date           Invoice_ID   Name     Description     Sale_Type      Amount
---------------------------------------------------------------------------
02.01.1991        1        John       Panado          Cash            50
02.02.1991        3        John       Oralox          Cash            60
02.03.1991        5        John       Zadin           Card            99
02.05.1991        6        John       Illiadin        Medical Aid     85
02.08.1991        8        John       Betamine        Cash            129

並且您需要返回所有行以及sub-total ,可以使用以下rollup功能生成所需的結果。

SELECT CASE
           WHEN (GROUPING(t1.name) = 1) THEN 'Sub-Total'
           ELSE ISNULL(t1.name, 'UNKNOWN')
       END AS Name,
       t1.date,
       t1.invoice_id,
       t1.description,
       t1.sale_type,
       sum(t1.Amount) as Amount
FROM t1
GROUP BY rollup((t1.date,t1.invoice_id,t1.name,t1.description,t1.sale_type));

結果:

Name                  date          invoice_id  description    sale_type      Amount
------------------------------------------------------------------------------------
John          02.01.1991 00:00:00       1         Panado         Cash           50
John          02.02.1991 00:00:00       3         Oralox         Cash           60
John          02.03.1991 00:00:00       5         Zadin          Card           99
John          02.05.1991 00:00:00       6         Illiadin       Medical Aid    85
John          02.08.1991 00:00:00       8         Betamine       Cash           129
Sub-Total                                                                       423

如果只需要在第一行中顯示name ,則必須將上述查詢用作inner query並在outer query使用另一種情況,如下所示。

SELECT CASE
           WHEN row_number() over(partition BY name
                                  ORDER BY name ASC) =1 THEN name
           ELSE NULL
       END, date, invoice_id,
                  description,
                  sale_type,
                  Amount
FROM
  (SELECT CASE
              WHEN (GROUPING(t1.name) = 1) THEN 'Sub-Total'
              ELSE ISNULL(t1.name, 'UNKNOWN')
          END AS Name,
          t1.date,
          t1.invoice_id,
          t1.description,
          t1.sale_type,
          sum(t1.Amount) AS Amount
   FROM t1
   GROUP BY rollup((t1.date,t1.invoice_id,t1.name,t1.description,t1.sale_type)) ) t;

結果:

Name                  date          invoice_id  description    sale_type      Amount
------------------------------------------------------------------------------------
John          02.01.1991 00:00:00       1         Panado         Cash           50
              02.02.1991 00:00:00       3         Oralox         Cash           60
              02.03.1991 00:00:00       5         Zadin          Card           99
              02.05.1991 00:00:00       6         Illiadin       Medical Aid    85
              02.08.1991 00:00:00       8         Betamine       Cash           129
Sub-Total                                                                       423

您可以在此處查看演示

希望這會有所幫助:-)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM