[英]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.