2017-09-13 1 views
0

Ich bin auf der Suche nach Hilfe mit SQL, dass ich völlig festgefahren bin. Noch relativ neu ...SQL-Gruppierungsergebnisse, Zwischensumme und Gesamtsumme

Hier ist, was ich im Moment mache:

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; 
    } 

Ich ziehe Daten von meiner Verkaufstabelle für einen Verkaufsbericht Typ-Funktionalität. Ich versuche, das zu verbessern, um es lesbarer/bedeutungsvoller zu machen. Wie Sie sehen können, erstelle ich die SQL-Anweisung mit Parametern basierend auf Eingaben des Benutzers. Dies ist wahrscheinlich nicht der beste Weg, dies zu tun.

Hier ist ein Beispiel dafür, wie die Ergebnisse aussehen, beim Laden der Formulare, meine SALES-Tabelle.

+----------+-------------+-----------+--------------+--------------+-------- 
| 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 
+----------+-------------+-----------+--------------+--------------+--------+ 

Die Ergebnisse werden ‚gefiltert‘ werden auf der Grundlage der eingegebenen Termine, Patienten_ID eingegeben, Namen oder Art des Verkaufs med.

Idealerweise möchte ich, so etwas haben (Patienten_ID ihrem Namen verknüpft ist):

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 

Für jeden Patienten - und dann ein Grand-total am Ende alle Teilsummen summieren.

Jede Hilfe hier würde absolut geschätzt werden. Vielen Dank.

+0

Teilen Sie bitte Probendaten in formatiertem Text. – zarruq

+0

@zarruq formatierten Text? würde ein Screenshot meiner Datagrid-Ergebnisse tun? – user3605194

+1

Beispieldaten Ihrer Datenbanktabellen "Verkauf" und "Patient" im Klartext. – zarruq

Antwort

0

Ausgehend von der Frage, dass Ihre table Beispieldaten wie folgt haben.

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 

und Sie müssen alle Zeilen zusammen mit sub-total zurückzukehren, Sie rollup Funktion wie unten verwenden können, das gewünschte Ergebnis zu erzielen.

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)); 

Ergebnis:

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 

Wenn Sie nur nur name in der ersten Reihe zu zeigen, haben Sie die obige Abfrage als inner query verwenden und einen anderen Fall in outer query wie unten zu verwenden.

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; 

Ergebnis:

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 

Sie können die Demo überprüfen here

Hope this :-) helfen.

Verwandte Themen