问个SQL列转换为行的语句怎么写

adrianEvin 2015-06-29 11:36:22
比如
字段1 字段2 字段3
中国 北京 100W人
中国 上海 200W人
中国 南京 300W人
想转化成
字段1 北京 上海 南京
中国 100W人 200W人 300W人
怎么写啊 这个语句
...全文
179 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ajianchina 2015-06-29
  • 打赏
  • 举报
回复
其实楼主写明了只要转换为行,那就先纵向将国别分组,横向就是一组的排列结果,逻辑类似这样:

List<string[]> list = new List<string[]>();
list.Add(new string[] { "中国", "北京", "100W人" });
list.Add(new string[] { "中国", "上海", "200W人" });
list.Add(new string[] { "中国", "南京", "300W人" });
list.Add(new string[] { "日本", "东京", "2人" });
list.Add(new string[] { "美国", "洛杉矶", "150W人" });
list.Add(new string[] { "日本", "大阪", "1人" });
list.Add(new string[] { "美国", "旧金山", "80W人" });

var query = list.GroupBy(p => p[0]).Select(p => p);
StringBuilder sb = new StringBuilder();
foreach(var p in query)
{
    string str = p.First()[0] + ":";
    foreach(string[] c in p)
    {
        str += "(" + c[1] + " " + c[2] + ")";
    }
    sb.AppendLine(str);
}
Console.WriteLine(sb.ToString());
输出: 中国:(北京 100W人)(上海 200W人)(南京 300W人) 日本:(东京 2人)(大阪 1人) 美国:(洛杉矶 150W人)(旧金山 80W人)
  • 打赏
  • 举报
回复
嗯,上面是手写的,没有用机器测试。其中的var是编译不过去的,再次修改一下呗,就是这样
public static DataTable GetPivot(List<ReportType> records)
{
    var result = new DataTable();
    result.Columns.Add("国家", typeof(string));    //定义第一列
    var columnNames = records.GroupBy(x => x.City).Select(g => g.Key).ToList();
    columnNames.ForEach(name => result.Columns.Add(name, typeof(string)));  //其它列
    records.ForEach(r =>
    {
        var dr = result.Rows
            .Cast<DataRow>()
            .Where(x => (string)x["国家"] == r.Country)
            .FirstOrDefault();
        if (dr == null)
        {
            dr = result.NewRow();       //创建新记录
            dr["国家"] = r.Country;         //第一列的值
            result.Rows.Add(dr);
        }
        dr[r.City] = r.Value;           //城市列对应的值
    });
    return result;
}
这次我拿机器编译了一下,可以编译通过。
  • 打赏
  • 举报
回复
上面的GetPivot 需要修改一下,需要将 X_Title 相同的 Value 在一行上,所以改为
public static DataTable GetPivot(List<ReportType> records)
{
    var result = new DataTable();
    result.Columns.Add("国家", typeof(string));    //定义第一列
    var columnNames = records.GroupBy(x => x.City).Select(g => g.Key).ToList();
    columnNames.ForEach(name => result.Columns.Add(name, typeof(string)));  //其它列
    records.ForEach(r =>
    {
        var dr = result.Rows
            .Cast<DataRow>()
            .Where(x => (string)x["国家"] == r.Country)
            .FirstOrDefault();
        if (dr == null)
        {
            var dr = result.NewRow();       //创建新记录
            dr["国家"] = r.Country;         //第一列的值
            dr[r.City] = r.Value;           //城市列对应的值
            result.Rows.Add(dr);
        }
        else
            dr[r.City] = r.Value;           //城市列对应的值
    });
    return result;
}
  • 打赏
  • 举报
回复
首先说,你这个业务数据设计得有些“荒唐”。除了中国以外,其它国家可能(其实根本就是)不会分成“北京、上海、南京.....”这样的城市,所以这个x-y坐标分解的思路根本就是荒唐的。可能你需要跟业务人员好好讨论一下,学习一下如何设计x-y坐标的问题。 抛开重要的基本业务概念理解来看技术,类似这类转换成动态表格的功能,我建议你在内存里转换。这样就可以把相同sql查询条件的实体数据缓存在一起。 例如,暂不考虑业务理解问题,先通过sql语句查询出列式数据实体
List<ReportType> result;
using (var conn = SqlHelper.OpenConnection())
{
    var cmd = SqlHelper.GetCommand(conn, "select * from [table] where [报告年份]=@year");
    SqlHelper.SetParameter(cmd, "year", 2015);
    result = (from IDataRecord rd in cmd.ExecuteReader()
                select new ReportType
                {
                    Countty = (string)rd["字段1"],
                    City = (string)rd["字段2"],
                    Value = (string)rd["字段3"],
                }).ToList();
}
这里的变量result返回你列出的数据集合。 那么,转换为一个DataTable就很容易,可以这样:
public static DataTable GetPivot(List<ReportType> records)
{
    var result = new DataTable();
    result.Columns.Add("国家",typeof(string));    //定义第一列
    var columnNames = records.GroupBy(x => x.City).Select(g => g.Key).ToList();
    columnNames.ForEach(name => result.Columns.Add(name, typeof(string)));  //其它列
    records.ForEach(r =>
    {
        var dr = result.NewRow();       //创建新记录
        dr["国家"] = r.Country;         //第一列的值
        dr[r.City] = r.Value;           //城市列对应的值
        result.Rows.Add(dr);
    });
    return result;
}
最后这个转换函数 GetPivot 的设计逻辑其实非常通用,基本上这类转换全都大同小异。你甚至可以把这里的 Contry、City 字段/属性名重新命名为 X_Title、Y_Title 从而可以把这个GetPivot 方法用于通用的目的。

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧