sql 具有多个 headers 和多个计数的查询
sql query with multiple headers and multiple counts
我有一个 table,其中包含客户任务的详细信息(附图)。我想要结果,例如每个客户在特定月份收到的任务数量,不。自开始之日起 5 天内完成的任务及其合规性。有人可以帮忙 SQL 查询
client | No.of tasks of a month | No.of tasks completed on time | % of compliance
A | 5 | 4 | 75%
假设您有一个非常新的 sql 服务器,尝试这样的操作(适当地更改 table 的名称和列)。
select
x.Client
, x.MonthTasks
, x.CompletedOnTime
, Compliance = x.CompletedOnTime * 100 / x.MonthTasks
from (
select
t.Client
, MonthTasks = Count(1)
, CompletedOnTime = SUM(CASE WHEN DATEDIFF(day, t.TaskStart, t.TaskEnd)<=5 THEN 1 ELSE 0 END)
from tasks as t
where
year(t.TaskStart) = 2018 -- put year
and month(t.TaskStart) = 10 -- put month
group by t.Client
) as x
order by x.Client
关于你最后的评论,这是一个最小的、尚未生产就绪的想法:
假设您有一个月份和年份的组合框
cbYear.DataSource = new int[] { 2017, 2018, 2019 };
cbMonth.DataSource = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dec" };
和一个 datagridview dgv,你可以这样做(在一个按钮中)
SqlConnection con = new SqlConnection("Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=test;Integrated Security=SSPI");
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = @"
select
x.Client
, x.MonthTasks
, x.CompletedOnTime
, Compliance = x.CompletedOnTime * 100 / x.MonthTasks
from (
select
t.Client
, MonthTasks = Count(1)
, CompletedOnTime = SUM(CASE WHEN DATEDIFF(day, t.TaskStart, t.TaskEnd)<=5 THEN 1 ELSE 0 END)
from tasks as t
where
year(t.TaskStart) = @year
and month(t.TaskStart) = @month
group by t.Client
) as x
order by x.Client
";
cmd.Parameters.AddWithValue("@year", cbYear.SelectedItem);
cmd.Parameters.AddWithValue("@month", cbMonth.SelectedIndex +1);
var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
var dt = new DataTable();
dt.Load(dr);
dgv.AutoGenerateColumns = true;
dgv.DataSource = dt;
dgv.Refresh();
我再说一遍,您必须捕获任何错误,也许可以在存储过程中转换查询,但这可以作为起点。
我有一个 table,其中包含客户任务的详细信息(附图)。我想要结果,例如每个客户在特定月份收到的任务数量,不。自开始之日起 5 天内完成的任务及其合规性。有人可以帮忙 SQL 查询
client | No.of tasks of a month | No.of tasks completed on time | % of compliance
A | 5 | 4 | 75%
假设您有一个非常新的 sql 服务器,尝试这样的操作(适当地更改 table 的名称和列)。
select
x.Client
, x.MonthTasks
, x.CompletedOnTime
, Compliance = x.CompletedOnTime * 100 / x.MonthTasks
from (
select
t.Client
, MonthTasks = Count(1)
, CompletedOnTime = SUM(CASE WHEN DATEDIFF(day, t.TaskStart, t.TaskEnd)<=5 THEN 1 ELSE 0 END)
from tasks as t
where
year(t.TaskStart) = 2018 -- put year
and month(t.TaskStart) = 10 -- put month
group by t.Client
) as x
order by x.Client
关于你最后的评论,这是一个最小的、尚未生产就绪的想法:
假设您有一个月份和年份的组合框
cbYear.DataSource = new int[] { 2017, 2018, 2019 };
cbMonth.DataSource = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dec" };
和一个 datagridview dgv,你可以这样做(在一个按钮中)
SqlConnection con = new SqlConnection("Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=test;Integrated Security=SSPI");
con.Open();
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = @"
select
x.Client
, x.MonthTasks
, x.CompletedOnTime
, Compliance = x.CompletedOnTime * 100 / x.MonthTasks
from (
select
t.Client
, MonthTasks = Count(1)
, CompletedOnTime = SUM(CASE WHEN DATEDIFF(day, t.TaskStart, t.TaskEnd)<=5 THEN 1 ELSE 0 END)
from tasks as t
where
year(t.TaskStart) = @year
and month(t.TaskStart) = @month
group by t.Client
) as x
order by x.Client
";
cmd.Parameters.AddWithValue("@year", cbYear.SelectedItem);
cmd.Parameters.AddWithValue("@month", cbMonth.SelectedIndex +1);
var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
var dt = new DataTable();
dt.Load(dr);
dgv.AutoGenerateColumns = true;
dgv.DataSource = dt;
dgv.Refresh();
我再说一遍,您必须捕获任何错误,也许可以在存储过程中转换查询,但这可以作为起点。