Linq查询分组数据

时间:2018-01-29 04:31:53

标签: asp.net entity-framework linq

我的数据如下:

Person Name, City, Profession
John, London,  Doctor
Bob, Sydney, Doctor
Jill, Hong Kong, Lawyer
Sarah, London, Accountant

城市名称按字母顺序排列

var cities = People.Select(x => x.City).OrderBy(x => x);

我想获得的数据格式是这样的:

name: "Doctor", data: [0, 1, 1] 

据说香港有0名医生,悉尼和伦敦有1名医生。

每个职业的最终结果应该是一行,每个城市都有一个数字。

因此,我的样本数据将是:

name: "Accountant", data: [0, 0, 1] 
name: "Doctor", data: [0, 1, 1] 
name: "Lawyer", data: [1, 0, 0] 

我尝试过以下查询:

var counts = People.GroupBy(p => p.Profession).Select(group =>
new
{
    Name = group.Key,
    Data = group.GroupBy(g => g.City).Select(c =>
            new
            {
                Count = c.Count()
            }),
});

但是这不起作用,因为内部查询只知道它自己的城市,所以响应不包括0,即它带回来:

name: "Accountant", data: [1] 
name: "Doctor", data: [1, 1] 
name: "Lawyer", data: [1] 

4 个答案:

答案 0 :(得分:0)

一种方法是以下

var professionList = People.Select (pl => pl.Profession).OrderBy(p=>p).Distinct();
    var citylist = People.Select(cl=>cl.City).OrderBy(c=>c).Distinct();
    foreach(var p in professionList)
    {
        Console.Write( String.Format("name:{0}, data:[ ",p));
        foreach(var c in citylist)
        {
            Console.Write(string.Format("{0},",
                People.Where (s=> s.Profession == p && s.City==c).Count()
            ));
        }
        Console.WriteLine("]");
    }   

结果

name:Accountant, data:[ 0,1,0]
name:Doctor, data:[ 0,1,1]
name:Lawyer, data:[ 1,0,0]

答案 1 :(得分:0)

        // get distinct professions
        var professions = peeps.Select(x => x.profession).Distinct().OrderBy(x => x).ToList();
        var citylist = new List<string>() { "Hong Kong", "Sydney", "London" };
        var res = new List<returndata>();
        foreach (var p in professions)
        {
            //init
            var thisres = new returndata()
            {

                ProfessionName = p,
                CityCount = new List<int>()
            };

            foreach (var c in citylist)
            {
                thisres.CityCount.Add(peeps.Where(pp => p == pp.profession && c == pp.city).Count());
            }

        }


    }
}

class returndata
{
    public string ProfessionName { get; set; }
    public List<int> CityCount { get; set; }
}

丑陋但这基本上就是你想要的。我不认为返回一个随机的int列表对每个城市的人数都有好处,但是你去了。

答案 2 :(得分:0)

如果城市只有3:

           List<Info> infos = new List<Info>()
        {
            new Info() {PersonName = "John", City = "London", Profession = "Doctor"},
            new Info() {PersonName = "Bob", City = "Sydney", Profession = "Doctor"},
            new Info() {PersonName = "Jill", City = "Hong Kong", Profession = "Lawyer"},
            new Info() {PersonName = "Sarah", City = "London", Profession = "Accountant"}
        };

        var newInfos = infos.GroupBy(x => x.Profession, x => x.City).Select(p => new
        {
            Name = p.Key,
            Data = $"[ {p.Count(x => x == "Hong Kong")}, " +
                   $"{p.Count(x => x == "Sydney")}, " + $"{p.Count(x => x == "London")}]"
        });
        // Ordering by name is not necessary
        foreach (var info in newInfos.OrderBy(x => x.Name))
        {
            Console.WriteLine($"{info.Name}, {info.Data}");
        }

更新:如果有很多城市:

 List<Info> infos = new List<Info>()
        {
            new Info() {PersonName = "John", City = "London", Profession = "Doctor"},
            new Info() {PersonName = "Bob", City = "Sydney", Profession = "Doctor"},
            new Info() {PersonName = "Jill", City = "Hong Kong", Profession = "Lawyer"},
            new Info() {PersonName = "Sarah", City = "London", Profession = "Accountant"}
        };
        var groupOfCities = infos.Select(x => x.City).Distinct();
        var newInfos = infos.GroupBy(x => x.Profession, x => x.City).Select(p => new
        {
            Name = p.Key,
            Data = "[ " + string.Join(", ", groupOfCities.Select(city => p.Count(x => x == city))) + "]"
        });
        foreach (var info in newInfos.OrderBy(x => x.Name))
        {
            Console.WriteLine($"{info.Name}, {info.Data}");
        }

答案 3 :(得分:0)

您可以Linq通过var myList = new List<Person> { new Person{ Name = "Jonh", City = "London", Profession = "Doctor" }, new Person{ Name = "Bob", City = "Sydney", Profession = "Doctor" }, new Person{ Name = "Jill", City = "Hong Kong", Profession = "Lawyer" }, new Person{ Name = "Sarah", City = "London", Profession = "Accountant" } }; var output = (from prof in myList.Select(x => x.Profession).Distinct() from city in myList.Select(x => x.City).Distinct() join profCity in myList on new { prof, city } equals new { prof = profCity.Profession, city = profCity.City } into subs from sub in subs.DefaultIfEmpty() group new { sub, city } by prof into res select new { name = res.Key, data = res.GroupBy(x => x.city).OrderBy(x => x.Key) .Select(x => x.Count(y => y.sub != null)).ToArray() }).OrderBy(x => x.name).ToList(); 发送completely solve

Accountant: [0, 1, 0]
Doctor: [0, 1, 1]
Lawyer: [1, 0, 0]

<强>结果:

{{1}}