I am new to LINQ.
I have the following table:
ID Field1 Field2 Field3
1 aaaa 20/01/2014 10
2 aaaa 21/01/2014 3
3 aaaa 25/01/2014 10
4 bbbb 01/01/2014 90
5 bbbb 03/01/2014 1
6 bbbb 31/01/2014 5
I want to group by Field1 and grab the last line of each group.
The SQL Query equivalent to this is:
SELECT Field1, Last(Field2) AS LastOfField2, Last(Field3) AS LastOfField3
FROM Table1
GROUP BY Field1
How this can be achieved on Linq?
var result = from p in Table1
group p by p.Field1 into grp
select grp.OrderByDescending(g=>g.Field2).First();
Related
I am trying to do the following but I cannot manage to get it right yet :(.
I have these tables:
table1 -> tb1_id, tb1_name
Sample Data:
--------------
1 group1
2 group2
3 group3
4 group4
5 group5
table2 -> tb2_id, tb2_sector, tb2_tb3_id
Sample Data:
--------------
1 alpha 1
2 beta 2
3 gamma 2
4 delta 2
5 epsilon 4
table3 -> tb3_id, tb3_mid, tb3_section
Sample Data:
--------------
1 234 alpha,beta,gama,delta
This is the output that I am looking for:
Name Count %
------ ----- -----
group1 1 25%
group2 3 75%
group3 0 0%
group4 0 0%
group5 0 0%
Basically I need a split a column value delimited by a comma (tb3_section in table3) and then find the right group for each value (table2 gives me the group id to link with table1) and then do a total count by group and get the percentage (assuming total is 100%).
This is the query I tried so far:
I searched for split value samples and found one that does the split by creating a numbers table first:
create table numbers (
`n` INT(11) SIGNED
, PRIMARY KEY(`n`)
)
INSERT INTO numbers(n) SELECT #row := #row + 1 FROM
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2,
(SELECT 0 UNION ALL SELECT 1) t8,
(SELECT #row:=0) ti;
Afterwards, I did this:
select tb3_section, count(1) from (
select
tb3_mid,
substring_index(
substring_index(tb3_section, ',', n),
',',
-1
) as tb3_section from table3
join numbers
on char_length(tb3_section)
- char_length(replace(tb3_section, ',', ''))
>= n - 1
) tb3_section_dashboard
group by 1
This doesn't give me the group count. Just does the split of tb3_section but doesn't give me the correct count and equivalent percentage. Any ideas will be much appreciate it thanks a lot.
LATEST UPDATE
First of all, I would like to thanks #eggyal for pointing me to the right direction and #Shadow for despise knowing that I was not taking the best approach, he came up with a quick fix to my problem. I managed to change the approach and removed the comma delimited values from table3. Instead now I add multiple rows for each new value (and added a constraint to avoid duplicates).
Now table3 looks like:
Sample Data:
--------------
1 234 alpha
2 234 beta
3 234 gama
4 234 delta
5 235 alpha
Here is the query I have taken from #shadow sample:
SELECT t1.tb1_name, COUNT(t3.tb3_section) AS no_per_group,
COUNT(t3.tb3_section) / t4.no_of_groups AS percentage
FROM t1 left
JOIN t2 ON t1.tb1_id=t2.tb2_tb3_id
INNER JOIN t3 ON t2.tb2_sector=t3.tb3_section>0
JOIN (SELECT COUNT(*) AS no_of_groups
FROM t3 INNER JOIN t2 ON t2.tb2_sector=t3.tb3_section>0) t4
GROUP BY t1.tb1_name
Instead of using find_in_set now I use = to match the exact value.
Now I get something like the following but the percentage looks odd and I miss a group that doesn't have a match:
Name no_per_group percentage
----- ------------- ----------
group1 2 0.1053
group3 3 0.1579
group4 3 0.1579
group5 3 0.1579
Although still I need something like:
Name Count %
------ ----- -----
group1 1 25%
group2 3 75%
group3 0 0%
group4 0 0%
group5 0 0%
Notice that if there is no match in a group, I still need to show that group.
Because I have thousands of records which are different from each other, I need to add another condition: where tb3_mid=234 . Likes this, the results are using to tb3_mid.
The best solution would be to redesign your table structure and move the data in the delimited values list to a separate table.
The quick solution is to utilise MySQL's find_in_set() function.
To get the total count of entries in the messages table (table3):
select count(*) as no_of_groups
from t3 inner join t2 on find_in_set(t2.tb2_sector,t3.tb3_section)>0
To get the counts per group, add a join to table1 and group by group name. To calculate the percentage, add the above query as a subquery:
select t1.tb1_name, count(t3.tb3_section) as no_per_group, count(t3.tb3_section) / t4.no_of_groups as percentage
from t1 left join t2 on t1.tb1_id=t2.tb2_tb3_id
inner join t3 on find_in_set(t2.tb2_sector,t3.tb3_section)>0
join (select count(*) as no_of_groups
from t3 inner join t2 on find_in_set(t2.tb2_sector,t3.tb3_section)>0) t4 --no join condition makes a Cartesian join
group by t1.tb1_name
I have the following table structure also i have mention my expected output
please help me with query as i dont know much about sql query
Table Structure
Table 1 : Emp Details
FName Id
Pratik 1
Praveen 3
Nilesh 2
Table 1 : JoinigDocument
id DocumentName
1 Leaving
2 Exp letter
3 birth cert
Table 2 : EmployeeJoiningDocument
EmpId JoiningDocumentId
1 1
1 2
3 1
3 2
3 3
2 1
2 3
Expected Output :
FName Id JoiningDocumentId DocumentName
Pratik 1 1 Leaving
Pratik 1 2 Exp letter
Pratik 1 null birth cert
Praveen 3 1 Leaving
Praveen 3 2 Exp letter
Praveen 3 3 birth cert
Nilesh 2 1 Leaving
Nilesh 2 null Exp letter
Nilesh 2 3 birth cert
You can write a query as:
select
A.FName,
A.Id,
B.JoiningDocumentId,
c.DocumentName
from #JoinigDocument C
cross join #EmployeeDetail A
Left join #EmployeeJoiningDocument B on B.EmployeeId = A.id and
B.JoiningDocumentId = C.id
order by A.Id
First cross join JoinigDocument and EmployeeDetail table so that you get all possible combinations of Employee and Documents irrespective of the fact that employee has that Joining Document or not. Then you need to do a left join to retain all these matches and find data corresponding to valid entries in EmployeeJoiningDocument.
Demo
I have the following data in a SQL Table:
I want to find 3 Consecutive data by No and group with ID. Result are
How to write query.please help.
Here is query which select only rows where actually 3 consecutive rows are:
SELECT a.*
FROM
TABLE as a
inner join
TABLE as b on (a.no+1=b.no and a.id=b.id)
inner join
TABLE as c on (a.no+2=c.no and a.id=c.id)
order by a.id, a.no
for your data it will provide:
4 a1 4
5 a1 3
1 a2 2
2 a2 4
3 a3 2
4 a3 3
rows (6,a1,1), (3,a2,5) and (5,a3,4) are not selected, as there are no (8,a1) (5,a2) and (7,a3)
DECLARE #temp TABLE (NO int,ID VARCHAR(2),QTY int)
INSERT INTO #temp
SELECT 1,'A1',5 UNION ALL
SELECT 4,'A1',4 UNION ALL
SELECT 5,'A1',3 UNION ALL
SELECT 6,'A1',1 UNION ALL
SELECT 7,'A1',0 UNION ALL
SELECT 9,'A1',5 UNION ALL
SELECT 12,'A1',3 UNION ALL
SELECT 1,'A2',2 UNION ALL
SELECT 2,'A2',4 UNION ALL
SELECT 3,'A2',5 UNION ALL
SELECT 4,'A2',1 UNION ALL
SELECT 7,'A2',4 UNION ALL
SELECT 9,'A2',5 UNION ALL
SELECT 1,'A3',0 UNION ALL
SELECT 3,'A3',2 UNION ALL
SELECT 4,'A3',3 UNION ALL
SELECT 5,'A3',4 UNION ALL
SELECT 6,'A3',2;
WITH tmpa AS
(
SELECT *
, NO - ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) AS grp
FROM #temp
)
, tmpb AS
(
SELECT *
, COUNT(*) OVER(PARTITION BY ID,grp) AS grpcount
FROM tmpa
)
SELECT NO,ID,QTY FROM tmpb WHERE grpcount>1;
Result are
4 A1 4
5 A1 3
6 A1 1
7 A1 0
1 A2 2
2 A2 4
3 A2 5
4 A2 1
3 A3 2
4 A3 3
5 A3 4
6 A3 2
I found this query from this link.
Find ānā consecutive free numbers from table
http://sqlfiddle.com/#!1/a2633/2
Answer Credit by
From the sql data below, I'd like to take a distinct EmpId that is the max ID.
ID EmpId DeptId
1 1002 XY
5 1100 ABC
6 1109 EF
7 1100 MN
9 1100 DE
10 1250 CE
11 1250 DJ
12 1100 DE
Results would look like the following:
ID EmpId DeptId
1 1002 XY
6 1109 EF
11 1250 DJ
12 1100 DE
How should this LINQ be structured?
var result = list.GroupBy(x=>x.EmpId).Select(g=>g.OrderByDescending(y=>y.Id).First());
from e in context.Employees
group e by e.EmpId into g
select new {EmpId = g.Key,
ID = g.OrderByDescending(gg=>gg.ID).FirstOrDefault().ID,
DeptId = g.OrderByDescending(gg=>gg.ID).FirstOrDefault().DeptId
}
I'm struggling to get some results from my database. I have a table like this:
ID ID_INVOICE PRODUCT QUANTITY PRODUCT_ID
------------------------------------------
1 1 aaa 3 2
2 1 bbb 2 3
3 1 ccc 1 4
4 2 bbb 3 3
5 2 aaa 3 2
So after the query I would like to get something like
aaa 6
bbb 5
ccc 1
The query is based on the ID_INVOICE so far I've tried this:
SELECT product, sum(quantity)
FROM product
WHERE invoice_id = #p1
Add a GROUP BY product clause, like so:
SELECT product, sum(quantity)
FROM product
WHERE invoice_id = #p1
GROUP BY product;
SQL Fiddle Demo