ASP.net Linq to SQL grouping and adding at the same time? - c#

I have a table of products
products:
ProdID | ProdName
1 | shirt
2 | pants
table of sizes:
SizeID | Size
1 | small
2 | med
3 | large
Table of orders
OrderID | ProdID | SizeID | Qty
1 | 1 | 1 | 4
2 | 1 | 1 | 3
3 | 1 | 2 | 2
4 | 2 | 1 | 1
5 | 2 | 3 | 1
How do I get results like this:
ProdName | Size | Total qty ordered (group by product and size add all quantities)
shirt | small | 7
shirt | med | 2
pants | small | 1
pants | large | 1
Thank you

from o in dc.Orders
group o by new { o.Product.ProdName, o.Size.Size } into g
select new { g.Key.ProdName, g.Key.Size, Total = g.Sum(or => or.Qty))};

Related

How to list the products under each category in sql? side by side

I'm a bit of a beginner in sql and I need your help.
I'm sorry that I don't know if the question is correct.
now the code gives this;
+---------+----------+-------------+------------+
| id | CompanyId| DealId | price |
+---------+----------+-------------+------------+
| 1 | 1 | 1 | 100 |
| 2 | 1 | 2 | 50 |
| 3 | 1 | 3 | 25 |
| 4 | 2 | 1 | 1000 |
| 5 | 2 | 2 | 2000 |
| 6 | 2 | 3 | 2500 |
+---------+----------+-------------+------------+
but this is what i want;
+---------+----------+-------------+------------+------------+--+
| id | companyId| DealName1 | DealName2 | DealName3 | |
+---------+----------+-------------+------------+------------+--+
| 1 | 1 | 100 | 50 | 25 | |
| 2 | 2 | 1000 | 2000 | 2500 | |
| 3 | 3 | value | value | value | |
| 4 | 4 | value | value | value | |
+---------+----------+-------------+------------+------------+--+
select CompanyId
,[1] as DealName1
,[2] as DealName2
,[3] as DealName3
from (select CompanyId, DealId, price from t) t
pivot (sum(price) for DealId in([1],[2],[3])) p
CompanyId
DealName1
DealName2
DealName3
1
100
50
25
2
1000
2000
2500
Fiddle

Most efficient way to query for multiple rows and their specific sub-items (e.g. A `Sale` table and its `Items`)

I have the following tables:
Sales Table:
+----+------------+
| ID | Date |
+----+------------+
| 1 | 11/20/2018 |
| 2 | 11/21/2018 |
+----+------------+
Items Table:
+----+------------+----------+-------+----------+
| ID | FK_Sale_ID | Quantity | Price | Subtotal |
+----+------------+----------+-------+----------+
| 1 | 1 | 5 | 100 | 500 |
| 2 | 1 | 3 | 50 | 150 |
| 3 | 2 | 5 | 60 | 300 |
+----+------------+----------+-------+----------+
Currently, I query for the Sale rows and then run another query for each to retrieve all of its Items after which, I initialize them as objects in my C# Program. My problem is that I frequently run into scenarios where I'm dealing with hundreds of sales at the same time. Because of this, I have to run hundreds of queries as well.
My question is, is there a more efficient way to query for all Sales and their Items or is this it? I thought of trying a query like
SELECT *
FROM items_table
WHERE FK_Sale_ID = '1' OR FK_Sale_ID = '2'
And then manually sorting which Item belonged to which sale for initialization but this query quickly got messy after dealing with more than a few sales. Any ideas?
You can use join clause to combine multiple tables data in your query:
SELECT *
FROM items_table
JOIN sales_table ON items_table.FK_Sale_ID = sales_table.ID
WHERE sales_table.Date = #somedate
With this query when #somedate = 11/20/2018 you basically will get this data in one go:
+----+------------+----+------------+----------+-------+----------+
| ID | Date | ID | FK_Sale_ID | Quantity | Price | Subtotal |
+----+------------+----+------------+----------+-------+----------+
| 1 | 11/20/2018 | 1 | 1 | 5 | 100 | 500 |
| 1 | 11/20/2018 | 2 | 1 | 3 | 50 | 150 |
+----+------------+----+------------+----------+-------+----------+
Use SELECT items_table.* to get all fields of items table only

Get record for each type with latest / bigger dates in C# DBML

I have a DB table which has some data as follows:
LINE | QTY | USERID | DATE
-----------------------------------------
1 | 5 | qb1 | 2015-03-02 11:23:25
2 | 1 | qb2 | 2015-03-02 18:24:03
3 | 3 | ch1 | 2015-03-03 05:38:49
1 | 2 | qb1 | 2015-03-03 08:47:02
2 | 4 | qb2 | 2015-03-03 14:01:31
3 | 2 | ch1 | 2015-03-03 21:11:53
1 | 4 | qb1 | 2015-03-04 09:34:04
2 | 5 | qb2 | 2015-03-04 15:29:27
3 | 1 | ch1 | 2015-03-04 19:28:33
As you can see I have only 3 unique LINE values in the DB. I require a LINQ query to select the latest record of every line. The date can be any date, I just need the latest status of the lines based on "DATE" field.
At the moment I am doing it very roughly something like this:
var line1 = db.GetTable<lnk_sts>().Where(x=> x.LINE== 1).OrderByDescending(x => x.DATE).FirstOrDefault();
Same for the other 2. What I Require is a list of lnk_sts with only the ones with a bigger date, in this case:
LINE | QTY | USERID | DATE
---------------------------------------
1 | 4 | qb1 | 2015-03-04 09:34:04
2 | 5 | qb2 | 2015-03-04 15:29:27
3 | 1 | ch1 | 2015-03-04 19:28:33
What you need to do is, group on Line and then take the first item in group after ordering in descending.
db.GetTable<lnk_sts>()
.GroupBy(x=>x.LINE)
.Select(x=>x.OrderByDescending(o=>o.DATE).FirstOrDefault())
.ToList();
First group by the line, then order by date and take the last item.
var result = db.GetTable<lnk_sts>().GroupBy(x=> x.LINE).Select(x => x.OrderBy(y => y.Date).Last())

assign unique group id to related values between two columns

I have a challenging problem.I am developing a web app (.net(C#)) that takes an specific excel file and export an delimited file with specifications explained below.
Here is the excel to be imported:
Loan_ID |Owner_Id | RelPerson_Id | Loan_Class
------------------------------------------------
L131231 | 1234 | 5678 | 0
L135148 | 2345 | 6789 | 2
L417128 | 1234 | 5432 | 1
L271237 | 5678 | 1112 | 5
L213781 | 2345 | 1113 | 4
L098932 | 1117 | 6789 | 6
L012213 | 1122 | 3311 | 2
L398721 | 2221 | 1112 | 3
L098766 | 5552 | | 1
Desired output:
Cust_ID | Cust_class | Gr_ID | Gr.Members | Gr_Class
---------------------------------------------------------------------
1234 | 1 | 1 | (1234,5678,5432,1112,2221) | 5
2345 | 4 | 2 | (2345,1117,6789,1113) | 6
5678 | 5 | 1 | (1234,5678,5432,1112,2221) | 5
1117 | 6 | 2 | (2345,1117,6789,1113) | 6
1122 | 2 | 3 | (1122,3311) | 2
6789 | 6 | 2 | (2345,1117,6789,1113) | 6
5432 | 1 | 1 | (1234,5678,5432,1112,2221) | 5
1112 | 5 | 1 | (1234,5678,5432,1112,2221) | 5
1113 | 4 | 2 | (2345,1117,6789,1113) | 6
3311 | 2 | 3 | (1122,3311) | 2
2221 | 3 | 1 | (1234,5678,5432,1112,2221) | 5
5552 | 1 | 4 | (5552) | 4
So,i will explain the case in order for you to understand.In the excel file, the first column represents the loan with unique id (no duplicates), the second column represent the Owner of the loan which is an id to identify the customer(Customer_Id).The id of Related person is also a Customer_Id which is the guarantor of the owner in this loan. A customer may have 2 or more loans and can be the guarantor in 2 or more other loans. The guarantor may be the guarantor in 2 or three loans but also may be the owner of another loan.So the owner_id and Rel_PersonId may have duplicates and the Rel_PersonId may have blank values . Class column is the rating or classification of the loan Id (Based on days in delay).
From this file i want the above output.
Cust_id is the distinct Customer Id which will be taken from both columns, Owner, and Rel Persons and will be assigned the highest class(Column :Cust_Class) of the loan he is part of(whether owner or guarantor).I already found a solution for the first two columns of the output, i am stuck with grouping.
Grouping logic:Two customers involved in one loan are grouped together, but if any of this customers is involved in another loan(wether like an Owner or a guarantor) with another Cutomer X, and in another with another customer Y both customers will be in a group with the first two, and if customer x or y are involved in other loans with other customers z and a those are added to the first group with the others too, and this cycle continues till there are no more customer connected with those that are already in the group.See the desired output for understanding.The group id will be generated automatically and sequentially(1,2,3,4) .The group class will be the class of the customer with the highest Cust_class of the group.
I am using sql server to import the excel.Any idea on how to build a query to gain this output or any other solutions?
Hope you can understand, feel free to ask for any further clarification.
Thank you.

Recent users query

I have 2 tables, for example let's assume that this is the data:
users table:
------------------------------
| user_id | username |
------------------------------
| 1 | danny |
| 2 | george |
| 3 | lana |
| 4 | kim |
| 5 | tim |
------------------------------
users_logins table:
-----------------------------------------------
| record_id | user_id | recorder |
-----------------------------------------------
| 1 | 3 | 2012-11-06 04:18:26 |
| 2 | 3 | 2012-11-06 04:31:05 |
| 3 | 2 | 2012-11-06 03:44:22 |
| 4 | 1 | 2012-11-06 04:18:58 |
| 5 | 1 | 2012-11-06 04:30:15 |
| 6 | 3 | 2012-11-06 04:31:05 | X
| 7 | 1 | 2012-11-06 05:53:47 |
| 8 | 1 | 2012-11-06 05:55:15 | X
| 9 | 4 | 2012-11-06 05:59:31 |
| 10 | 4 | 2012-11-06 06:12:55 | X
-----------------------------------------------
I want to show 3 recent logged in users, so the result will show only the rows that marked with X right to them, or in words unique recent logins.
How would the query look like?
Try this for linq to objects
(from login in users_logins.OrderByDescending(user => user.recorder)
from user in users
where user.user_id == login.user_id
select user).Distinct().Take(3)
This query
1. first sorts on date
2. then joins sorted login data with user data,
3. then take distinct users
4. and then finally take first 3 records.
Following is alternative query
from login in users_logins.OrderByDescending(user =>user.recorder).GroupBy(user=>user.recorder).SelectMany( users=>users.First()).Take(3)
from user in users
where user.user_id == login.user_id
select user
This query
1. first sorts
2. then groups on user_id
3. then take first 3 records with different user id,
4. then joins with users data.
I think this is what you want.
var resentLogedInUsers =
users
.Join(
users_logins,
u => u.user_id,
l => l.user_id,
(u, l) => new
{
User = u,
Login = l.recorder
})
.GroupBy(j => j.User)
.Select(l => new {User = l.Key, LastLogin = l.Max(d => d.Login)})
.OrderByDescending(r => r.LastLogin)
.Take(3);

Categories