我正在寻找我完全坚持的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;
}
我从Sales表中提取数据以获取销售报表类型功能。我希望改进它,使其更具可读性/意义。如您所见,我正在使用基于用户输入的参数构建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
对于每位患者 - 然后是最后的总计,以总结所有小计。
这里的任何帮助都绝对值得赞赏。谢谢。
答案 0 :(得分: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 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
您可以查看演示 here
希望这会有所帮助: - )。