2017-09-13 165 views
0

我正在尋找與SQL完全銜接的幫助。還是比較新的...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 
+----------+-------------+-----------+--------------+--------------+--------+ 

結果將根據輸入日期,patientID輸入,醫療名稱或銷售類型進行「篩選」。

理想我想有這樣的事情(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 

對於每一個病人 - 再隆重,總在最後總結了所有的小計。

任何援助在這裏絕對將不勝感激。謝謝。

+0

請以格式文本分享樣本數據。 – zarruq

+0

@zarruq格式化文本?我的數據網格結果的屏幕截圖會怎樣? – user3605194

+1

用純文本編號數據庫表「sale」和「patient」的樣本數據。 – zarruq

回答

0

假設您的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 queryouter 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 

您可以查看演示here

希望這將有助於:-)。