2017-09-13 16 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、販売名、または販売タイプに基づいて「フィルタリング」されます。各患者のために

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 

- して、最後に壮大-合計は、すべての小計を合計する:

は、理想的には私は(patientIDが自分の名前にリンクされている)、このような何かを持っていると思います。

ここにお手伝いがあれば幸いです。ありがとうございました。

+0

サンプルデータを書式付きテキストで正しく共有します。 – zarruq

+0

@ zarruq書式付きテキスト?私のDataGridの結果のスクリーンショットはありますか? – user3605194

+1

いいえデータベーステーブルの「販売」と「患者」のサンプルデータをプレーンテキストで表しています。 – 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 

は、あなたは、あなたの希望する結果を生成するために、以下のようにrollup機能を使用することができ、sub-totalと一緒にすべての行を返す必要があります。

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 

あなただけのだけ、あなたはinner queryとして上記のクエリを使用すると、以下のようouter queryに別のケースを使用する必要が最初の行のnameを表示する必要がある場合。

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

これは:-)役立つことを願っていますを確認することができます。