linq query depending on first column - sql

my table data is like this,
col1 col2 col3
A A1 1
B B1 1
A A2 1
B B2 1
C C1 1
D D1 1
E E1 1
A A3 1
so I want data like this
A 3 3
B 2 2
C 1 1
D 1 1
E 1 1
how can i query in linq please

var result = db.MyData
.GroupBy(x => x.Column1)
.Select(x => new {
Column1 = x.Key,
Count = x.Count(),
Sum = x.Sum(y => y.Column3)
});
Here is a sample:
void Main()
{
var myData = new[] {
new {col1="A", col2="A1", col3=1},
new {col1="B", col2="B1", col3=1},
new {col1="A", col2="A2", col3=1},
new {col1="B", col2="B2", col3=1},
new {col1="C", col2="C1", col3=1},
new {col1="D", col2="D1", col3=1},
new {col1="E", col2="E1", col3=1},
new {col1="A", col2="A3", col3=1}
};
var result = myData
.GroupBy(x => x.col1)
.Select(x => new
{
Column1 = x.Key,
Count = x.Count(),
Sum = x.Sum(y => y.col3)
});
result.Dump(); // LinqPad
}
Output:
Column1,Count,Sum
A 3 3
B 2 2
C 1 1
D 1 1
E 1 1

Related

Cross table VB.NET & SQL Server & Linq

I have a table like this:
MAName feldtext
------------------
karl fieldtext1
karl fieldtext2
karl fieldtext1
karl fieldtext3
karl fieldtext4
karl fieldtext2
karl fieldtext5
karl fieldtext3
karl fieldtext3
susi fieldtext1
susi fieldtext4
john fieldtext2
john fieldtext5
john fieldtext5
and I need:
MAName fieldtext1 fieldtext2 fieldtext3 fieldtext4 fieldtext5 FehlerJeMA
karl 2 2 3 1 1 9
susi 1 0 0 1 0 2
john 0 1 0 0 2 3
The columns fieldtext can go from fieldtext1 to fieldtextn, it's dynamic, depending on query.
I was looking here for solutions and found, so my approach:
Dim dt2 As New DataTable
Dim nn As Integer = 0
Dim Zeile As DataRow
dt2.Columns.Add("MAName")
' fieldtext distinct
Dim query2 = (From dr In (From d In newTable2.AsEnumerable Select New With {.feldtext1 = d("feldtext")}) Select dr.feldtext1 Distinct)
For Each Feldtext In query2
dt2.Columns.Add(Feldtext)
Next
column = New DataColumn()
column.DataType = System.Type.GetType("System.Int32")
column.ColumnName = "FehlerJeMA"
dt2.Columns.Add(column)
' MAName distinct
Dim query3 = (From dr In (From d In newTable2.AsEnumerable Select New With {.MAName2 = d("MAName")}) Select dr.MAName2.ToString.ToLower Distinct)
For Each Mitarbeiter In query3
Zeile = dt2.NewRow()
Zeile(0) = Mitarbeiter.ToString.ToLower
MA2 = Mitarbeiter.ToString.ToLower
nn = 1
For Each colName2 In query2
Fehler2 = colName2
Dim AnzahlFehler As String = (From row In newTable2.Rows Select row Where row("MAName").ToString.ToLower = MA2 And row("feldtext") = Fehler2).Count
If AnzahlFehler = 0 Then
AnzahlFehler = ""
End If
Zeile(nn) = AnzahlFehler
nn += 1
If AnzahlFehler <> "" Then
FehlerJeMA += CInt(AnzahlFehler)
End If
Next
Zeile(nn) = FehlerJeMA
dt2.Rows.Add(Zeile)
Next
This works, but is very slow...
It could be the case that in my table has more than 10.000 rows...
So my question is: what is fastest approach to get the result?
Is it some kind of cross table with linq? Other approaches?
In C# you will be able to use the code, try to translate it for your problem:
var pivotData = data.GroupBy(x => new {x.MAName, x.feldtext}, (key, group) => new { MAName = key.Column1, feldtext = key.Column2, count = group.Count() });

Linq query with GROUP BY on multiple fields, SUM and COUNT

I'm trying to use a LINQ SQL to query my database.
Let's say I have some data that looks like this:
var1 var2 var3 qty
1 a 1a 50
1 a 1a 25
2 b 2b 10
2 b 2b 15
2 b 2b 10
3 a 3a 25
I know how to format my query in SQL. It would be something like this:
SELECT var1, var2, var3, count(*) AS count, sum(qty) As quantity
FROM MyTable
GROUP BY var1, var2, var3
In this case the output would be something like this:
var1 var2 var3 Count Qty
1 a 1a 2 75
2 b 2b 3 35
3 a 3a 1 25
How can I do the same thing with LINQ in vb.net
Dim groups = From j In MyTable
Group By j.var1, j.var2, j.var3 Into g
Select new {var1 = g.var1,
var2 = g.var2,
var3 = g.var3,
quantity = sum(g.qty),
count = count(*)}
That's not quite right, but I think it's close. I don't understand the syntax of the group by in VB.NET.
You want to group by an anonymous type, this is the syntax in VB.NET (note the Key):
Dim groups =
From j In MyTable
Group By x = New With {Key .var1 = j.var1, Key .var2 = j.var2, Key .var3 = j.var3} Into g = Group
Select New With {
.var1 = x.var1,
.var2 = x.var2,
.var3 = x.var3,
.quantity = g.Sum(Function(r) r.qty),
.count = g.Count()
}
You will have to use anonymous type like this:-
Group j By Key = New With { Key .Var1 = j.var1,
Key .Var2 = j.var2,
Key .Var3 = j.var3 } Into Group
Select New With { .var1 = Key.Var1,
.var2 = Key.Var2,
.var3 = Key.Var3,
.quantity = Group.Sum(Function(x) x.qty),
.count = Group.Count()
}

Linq Group by a field and count distinct by another

I have a datatable and I want to use LINQ to get the equivalent of
Select barid, count(distinct bar) as barCount
From myTable
Group By barid
The data is in the form:
barid bar
4 1
4 1
4 1
12 2
12 2
12 2
12 3
13 1
13 2
13 3
The result should be:
barid, barCount
4 1
12 2
13 3
Can you help?
I cannot translate it into vb.net but the c# equivalent would be:
var result = from record in data
group record by record.barid into grp
select new
{
barid = grp.Key,
barCount = grp.Select( item => item.bar ).Distinct( ).Count( )
};
Considering your DataTable columns to be of type Integer, you can use below query:-
Dim result = dt.AsEnumerable().GroupBy(Function(x) x.Field(Of Integer)("barid")) _
.[Select](Function(x) New With { _
Key .barid = x.Key, _
Key .barCount = x.[Select](Function(z) z.Field(Of Integer)("bar")) _
.Distinct().Count()})
Then you can simply use the ForEach like this:-
For Each x In result
Console.WriteLine("barid {0}",x.barid)
Console.WriteLine("barCount {0}", x.barCount)
Console.WriteLine("---------------")
Next
This is giving me the following output:-

Multi-Group Column Count Linq

I have,
A list, MyList, of objects with fields:
string A;
string B;
Conceptually, this is similar to a two column SQL Table with columns A, B.
I'm trying to create a linq expression that would produce the three column result set of this T-SQL on such a conceptual table:
SELECT A, B, COUNT(B)
FROM T1
GROUP BY A, B
That is, if I had a table such as:
A B
----------
x g
x g
x g
x s
y g
y g
I would expect:
A B COUNT(B)
-------------------------
x g 3
x s 1
y g 2
My best efforts were this:
var result = from MyObjs in MyList
group MyObjs by new { MyObjs.A, MyObjs.B } into g
select new { g.Key.A, g.Key.B, g.Key.B.Count() }
But the count appears to return the total number of B's not the number of B's per multiple column group. How can this be fixed?
Try this.... (off the top of my head)
var result = from MyObjs in MyList
group MyObjs by new { MyObjs.A, MyObjs.B } into g
select new { g.Key.A, g.Key.B, MyCount = g.Count() }
Or if you prefer...
var result = MyList.GroupBy(x => new {x.A, x.B})
.Select(g => new {g.Key.A, g.Key.B, MyCount = g.Count()});

LINQ Group by and Sum syntax

i have the following vb.net LINQ Query
Dim q = From row In dx.AsEnumerable
Group row By G = New With {.Cat = row.Field(Of Integer)("catalogid")}.Cat,
New With {.Backorder = row.Field(Of Integer)("backorder")}.Backorder Into pg = Group
Select New With
{
.Cat = pg.Cat,
.Backorder = pg.Sum(Function(x) x.Backorder)
}
i have this datatable called dx
catalogid backorder
1 5
1 10
2 1
2 5
i want to Sum backorder column where catalogid is the same so the result is the following
catalogid backorder
1 15
2 6
in the Select new with part, what is wrong?
Try following...
var result = dx.AsEnumerable()
.GroupBy(row => row.Field<int>("catalogid"))
.Select(group => group.Sum(item => item.Field<int> ("backorder")).CopyToDataTable();
or
var result= from s in dx.AsEnumerable()
group s by s.Field<int>("catalogid") into grp
select new {
CatalogId= grp.Key,
Back Order = grp.Sum(r => r.Field<int>("backorder"))
};
DataTable datatbl = result.CopyToDataTable();