C# 从数据库绑定数据并旋转/转置数据

C# 从数据库绑定数据并旋转/转置数据,c#,sql,asp.net,C#,Sql,Asp.net,我想从SQL数据库中检索数据并绑定到控件(Datagridview/Datalist)。制作一个表格格式输出,它将行显示为列,列显示为行 我有一个表:tbl_CustData,有两个字段,例如FixedDepDate(datetime数据类型),另一个是月\年(nvarchar数据类型)。数值如下: FixedDepDate | Month_year | -------------------------+---------------+ 2018-07-03 00

我想从SQL数据库中检索数据并绑定到控件(Datagridview/Datalist)。制作一个表格格式输出,它将行显示为列,列显示为行

我有一个表:tbl_CustData,有两个字段,例如FixedDepDate(datetime数据类型),另一个是月\年(nvarchar数据类型)。数值如下:

 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
我已经尝试了以下方法,但没有得到我期望的结果

  • 使用Datalist/Gridview控件并尝试绑定数据
  • 使用了PIVOTE运算符,但未获取输出
  • 另外,请给出一些想法,哪个控件适合绑定数据并显示在我的网页上,或者任何解决此问题的技术。
    注意:我没有使用任何事件来显示我的输出。希望在运行项目后直接在我的页面上显示我的输出。

    您可以按年份、月份分组,然后将该期间的天数合计。即:

    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();
    }