c# - C# windows 窗体在 datagridview 中显示 0,其中按小时分组的数据,但 SQL 开发人员显示正确的结果
问题描述
我在 Oracle 中有一个查询,按小时显示事务数,然后最后一列显示所有小时的总和。该查询在 SQL 开发人员中运行良好。但是,当我尝试在我的 Windows 窗体应用程序的 datagridview 中显示结果时,我得到所有小时数据的 0。但是,我确实得到了最终总数。
这是我第一次在使用日期选择器和在 datagridview 中显示数据时遇到问题。
这是 SQL developer 中结果的屏幕截图(我意识到总列不等于显示的列的总数。屏幕截图未显示所有列。)
这是窗口表单中相同数据的屏幕截图。
这就是我认为是相关的 SQL 代码。如果过分请见谅。
SELECT
user_name,
SUM(CASE
WHEN substr(hr,11) = '19:00:00' THEN t
ELSE 0
END) AS eight_pm,
SUM(CASE
WHEN substr(hr,11) = '20:00:00' THEN t
ELSE 0
END) AS nine_pm,
SUM(CASE
WHEN substr(hr,11) = '21:00:00' THEN t
ELSE 0
END) AS ten_pm,
SUM(CASE
WHEN substr(hr,11) = '22:00:00' THEN t
ELSE 0
END) AS eleven_pm,
SUM(t) total
FROM
(
SELECT
user_name,
COUNT(*) t,
TO_CHAR(trunc(last_update_date,'HH24') ) AS hr
FROM
cte
GROUP BY
user_name,
TO_CHAR(trunc(last_update_date,'HH24') )
)
GROUP BY
user_name
ORDER BY
user_name
除了将日期选择器用作参数来查询数据之外,我没有对日期选择器做任何事情。如有必要,我可以显示自定义格式或一些 C# 代码。
请注意,直到明天早上我才能测试任何解决方案。感谢您的时间。
更新 添加用于填充 datagridview 的代码:
private void btnSecondShiftStats_Click(object sender, EventArgs e)
{
var start = startDatePicker.Value;
var end = endDatePicker.Value;
string name = tbName.Text;
dvgSecondShiftStats.DataSource = _secondShiftStatsData.GetStats(start, end, name);
}
GetStats 方法:
public List<SecondShiftStats> GetStats(DateTime fromDate, DateTime toDate, string uName)
{
var statList = new List<SecondShiftStats>();
var conString = ConfigurationManager.ConnectionStrings["SecondShiftStatsConnection"].ConnectionString;
using (OracleConnection con = new OracleConnection(conString))
{
string sql = @"WITH loaded AS (
SELECT...";
using (OracleCommand cmd = new OracleCommand(sql, con))
{
cmd.Parameters.Add(new OracleParameter(":start_time", OracleDbType.Date)).Value = fromDate;
cmd.Parameters.Add(new OracleParameter(":end_time", OracleDbType.Date)).Value = toDate;
cmd.Parameters.Add("name", uName);
con.Open();
using (OracleDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var stats = new SecondShiftStats();
stats.USER_NAME = reader["USER_NAME"].ToString();
stats.THREE_PM = Convert.ToInt32(reader["THREE_PM"]);
stats.FOUR_PM = Convert.ToInt32(reader["FOUR_PM"]);
stats.FIVE_PM = Convert.ToInt32(reader["FIVE_PM"]);
stats.SIX_PM = Convert.ToInt32(reader["SIX_PM"]);
stats.SEVEN_PM = Convert.ToInt32(reader["SEVEN_PM"]);
stats.EIGHT_PM = Convert.ToInt32(reader["EIGHT_PM"]);
stats.NINE_PM = Convert.ToInt32(reader["NINE_PM"]);
stats.TEN_PM = Convert.ToInt32(reader["TEN_PM"]);
stats.ELEVEN_PM = Convert.ToInt32(reader["ELEVEN_PM"]);
stats.TOTAL = Convert.ToInt32(reader["TOTAL"]);
statList.Add(stats);
}
}
}
}
return statList;
}
解决方案
我想出了解决这个问题的办法。我有另一个应用程序显示相同的查询,但没有分组。我在 sql developer 和 datagridview 中看到了日期时间格式的差异。
SQL开发人员:
数据网格视图:
最后是 Datetimepicker 的格式:
我从未改变 datgridview 显示日期的方式。我只自定义了 datetimepicker 并将其用作查询中的参数。这似乎是问题所在。
因此,我将 select 语句中的相关列更改为:
TO_CHAR(last_update_date, 'DD/MON/YYYY HH24:MI:SS')AS last_update_date.
当然,我知道我必须将最终选择更改为:
select ...
case when substr(hr,11)...
至
select ...
case when substr(hr,13)...
或者我是这么想的。当我尝试在 SQL Developer 中运行查询时,我会收到 ORA-01722: invalid-number 消息。
我再次确定它在分组语句中,并寻找按小时分组的其他解决方案。我尝试使用此Stack Overflow question中接受的答案,但收到一条消息,指出小时数必须在 1 到 12 之间,即使我的格式设置为“HH24”。
为了解决这个问题,我将最终的子查询更改为:
SELECT
user_name,
SUM(CASE
WHEN hr = '19' THEN t
ELSE 0
END) AS eight_pm,
SUM(CASE
WHEN hr = '20' THEN t
ELSE 0
END) AS nine_pm,
SUM(CASE
WHEN hr = '21' THEN t
ELSE 0
END) AS ten_pm,
SUM(CASE
WHEN hr = '22' THEN t
ELSE 0
END) AS eleven_pm,
SUM(t) total
FROM
(
SELECT
user_name,
COUNT(*) t,
substr(last_update_date,13,2)as hr
FROM
cte
GROUP BY
user_name,
substr(last_update_date,13,2)
)
group by
user_name
order by
user_name
进行这些更改后,我的应用程序会显示我期望的结果:
推荐阅读
- python - 如何在 Django 中实现 chart.js?
- jquery - jQuery Validate 插件和 NiceSelect:验证错误
- python - 如何返回与列表中的项目匹配的 arangodb 文档列表?
- c# - 无法使用保存的信息加载到数组中
- c++ - 假设派生类的指针与第一个基类的指针相同有多安全?
- javascript - Katex 自动渲染在 Vue 项目中不起作用
- php - PHP:如何使 INVOKING 内部函数更快
- node.js - 启用 CLIENT_SESSION_KEEP_ALIVE 是否会使 Snowflake 基础设施不断启动?
- java - 如果列表尚未包含包含键值对的映射,如何有条件地将映射插入 Java 中的列表
- fabricjs - fabric.js 3.6 - 更改分组对象时,组的边界框不会更新