C# 从数据库绑定数据并旋转/转置数据
我想从SQL数据库中检索数据并绑定到控件(Datagridview/Datalist)。制作一个表格格式输出,它将行显示为列,列显示为行 我有一个表:tbl_CustData,有两个字段,例如FixedDepDate(datetime数据类型),另一个是月\年(nvarchar数据类型)。数值如下:C# 从数据库绑定数据并旋转/转置数据,c#,sql,asp.net,C#,Sql,Asp.net,我想从SQL数据库中检索数据并绑定到控件(Datagridview/Datalist)。制作一个表格格式输出,它将行显示为列,列显示为行 我有一个表:tbl_CustData,有两个字段,例如FixedDepDate(datetime数据类型),另一个是月\年(nvarchar数据类型)。数值如下: FixedDepDate | Month_year | -------------------------+---------------+ 2018-07-03 00
FixedDepDate | Month_year |
-------------------------+---------------+
2018-07-03 00:00:00.000 | March - 18 |
2018-08-23 00:00:00.000 | August - 2018 |
2018-08-29 00:00:00.000 | August - 2018 |
2018-07-04 00:00:00.000 | July - 2018 |
2018-07-10 00:00:00.000 | July - 2018 |
2018-07-25 00:00:00.000 | July - 2018 |
预期输出为:
March - 18 | 03
July - 18 | 04 | 10 | 25
August - 18 | 23 | 29
我已经尝试了以下方法,但没有得到我期望的结果
注意:我没有使用任何事件来显示我的输出。希望在运行项目后直接在我的页面上显示我的输出。您可以按年份、月份分组,然后将该期间的天数合计。即:
var result = from d in db.MyTable.AsEnumerable()
group d by d.FixedDepDate.ToString("MMMM-yyyy")
into g
select new
{
Period = g.Key,
Days = string.Join(" | ", g.Select(x => x.FixedDepDate.Day))
};
根据样本数据(已更正),输出为:
Period Days
March-2018 7
August-2018 23 | 29
July-2018 4 | 10 | 25
我不明白为什么要在t-SQL中绑定到DataGridView时需要它。无论如何:
CREATE TABLE #temp (
[FixedDepDate] DATETIME );
INSERT INTO #temp
(
[FixedDepDate]
)
VALUES
('2018-03-07 00:00:00.000'),
('2018-08-23 00:00:00.000'),
('2018-08-29 00:00:00.000'),
('2018-07-04 00:00:00.000'),
('2018-07-10 00:00:00.000'),
('2018-07-25 00:00:00.000');
SELECT ym.YearMonth,
(
SELECT RIGHT('0' + LTRIM(STR(DAY(FixedDepDate))), 2) + ' | '
FROM #temp t
WHERE YEAR(t.FixedDepDate) = ym.y
AND MONTH(t.FixedDepDate) = ym.m
FOR XML PATH('')
) AS [Days]
FROM
(
SELECT DISTINCT
DATENAME(MONTH, FixedDepDate) + ' - ' + DATENAME(YEAR, FixedDepDate) AS YearMonth,
YEAR(FixedDepDate) AS y,
MONTH(FixedDepDate) AS m
FROM #temp
) AS [ym]
ORDER BY y,
m;
DROP TABLE #temp;
你应该从一开始就清楚地解释你想要什么
CREATE TABLE #temp
(
[FixedDepDate] DATETIME
);
INSERT INTO #temp
(
[FixedDepDate]
)
VALUES
('2018-03-07 00:00:00.000'),
('2018-08-23 00:00:00.000'),
('2018-08-29 00:00:00.000'),
('2018-07-04 00:00:00.000'),
('2018-07-10 00:00:00.000'),
('2018-07-25 00:00:00.000');
WITH source AS
(
SELECT
YEAR(FixedDepDate) AS y,
MONTH(FixedDepDate) AS m,
DATENAME(MONTH, FixedDepDate) + ' - ' +
DATENAME(YEAR, FixedDepDate) AS YearMonth,
ROW_NUMBER() OVER (
PARTITION BY YEAR(FixedDepDate) * 10000 +
MONTH(FixedDepDate)
ORDER BY DAY(FixedDepDate)) AS nDay,
RIGHT('0' + LTRIM(STR(DAY(FixedDepDate))), 2) AS cDay
FROM #temp
)
SELECT YearMonth, [1], [2], [3]
FROM source
PIVOT ( max(cDay)
FOR [nDay] IN ( [1], [2], [3] )
) pvt
ORDER BY y,m;
DROP TABLE #temp;
编辑:
您没有指定后端。这可能在后端解决,如果它是其中之一,使这类事情或前端简单。我使用SQL Server作为后端。这是正确的。但我想在单独的列中显示月份的天数。根据您的查询,表示在单列中显示的“天”。如果月份有3天,则每个月将显示3个不同的列,即2018年4月-2018年,3个不同的列中有3个日期。是的。。!!!这是预期的结果。唯一的问题是,在[nDay]in()语句中,按照日期手动获取[1]、[2]、[3]列。现在我想动态创建列。例如:如果八月有3个日期,那么它应该根据您的查询显示3个日期。它应该根据日期(cDay)显示列。@PankajSonawane,很容易获得C#中的最大日数,并动态创建“[1]、[2]、[3]”部分。我理解,但您可以在查询中更改我的预期输出吗?请看…@PankajSonawane,为C代码编辑。下次请你自己做这些简单的事情,不要打电话给别人来写你的代码。
void Main()
{
DataTable tbl = new DataTable();
using (SqlConnection con = new SqlConnection(@"server=.\SQLExpress2012;Database=Test;Trusted_connection=yes"))
{
con.Open();
var columns = Convert.ToInt32(new SqlCommand(@"SELECT MAX(cnt)
FROM
(
SELECT COUNT(*) AS cnt
FROM MyDates
GROUP BY YEAR(FixedDepDate),
MONTH(FixedDepDate)
) tmp;", con)
.ExecuteScalar());
var collist = string.Join(",", Enumerable.Range(1, columns).Select(e => $"[{e}]"));
var pivot = $@"WITH source AS
(
SELECT
YEAR(FixedDepDate) AS y,
MONTH(FixedDepDate) AS m,
DATENAME(MONTH, FixedDepDate) + ' - ' +
DATENAME(YEAR, FixedDepDate) AS YearMonth,
ROW_NUMBER() OVER (
PARTITION BY YEAR(FixedDepDate) * 10000 +
MONTH(FixedDepDate)
ORDER BY DAY(FixedDepDate)) AS nDay,
RIGHT('0' + LTRIM(STR(DAY(FixedDepDate))), 2) AS cDay
FROM Mydates
)
SELECT YearMonth, {collist}
FROM source
PIVOT ( max(cDay)
FOR [nDay] IN ( {collist} )
) pvt
ORDER BY y,m;
";
tbl.Load( new SqlCommand(pivot,con).ExecuteReader());
con.Close();
}
var f = new Form();
var dgv = new DataGridView {Dock=DockStyle.Fill, DataSource=tbl};
f.Controls.Add(dgv);
f.Show();
}