How to join two tables and make group by in Linq - linq

I have a question about Linq select statement. I am new to Linq so any help will be very helpful. I did a lot of research but I still didn't manage to write down correct Linq statement.
I have this two tables and attributes:
Table Titles(title_id(PK), title) and
Table Sales(title_id(PK), qty)
where are title_id and title string values and qty is a number which represents some quantity.
I need to write a select which will take five most selling titles from this two tables.
So, I need to make sum from qty (we can have more records with the same Sales.title_id attribute) and make group by title_id and order by sum(qty) descending and then return attributes title and title_id.
How can I make suitable solution for my question?
Regards,
Dahakka

You can do group join of tables by title_id (each group g will represent all sales of joined title). Then select title description and total of sales for that title. Order result by totals, select title and take required number of top sales titles:
var query = (from t in db.Titles
join s in db.Sales on t.title_id equals s.title_id into g
select new { Title = t.title, Total = g.Sum(x => x.qty) } into ts
orderby ts.Total descending
select ts.Title).Take(5);
Resulting SQL will look like:
SELECT TOP (5) [t2].[title] AS [Title], [t2].[value] AS [Total]
FROM (
SELECT [t0].[title_id], (
SELECT SUM([t1].[qty])
FROM [Sales] AS [t1]
WHERE [t0].[title_id] = [t1].[title_id]
) AS [value]
FROM [Titles] AS [t0]
) AS [t2]
ORDER BY [t2].[value] DESC

Following is the linq query in method syntax
sales.GroupBy(s=>s.title_id)
.Select ( x =>
new {
Title_id = x.Key,
Sales= x.Sum (x=> x.qty)
})
.OrderByDescending(x=>x.Sales).Take(5)
.Join( titles,
sale=>sale.Title_id,
title=> title.title_id,
(sale, title)=> new
{
Title = title.Title,
TotalSales=sale.Sales
}
);

Related

LEFT JOIN three tables and SUM in LINQ

I have three tables:
products purchased (RecordEntered as A)
products sold in the country (SoldInCountry as B)
products sold outside the country (SoldOutCountry as C)
Each record in A could be:
entered and not yet sold
entered and sold only in the country
entered and sold only out of the country
entered and sold in the country and also outside the country
I started grouping the pieces in table B like so:
SELECT
A.IdRecord, A.Qty, sum(isnull(B.Qty,0)) AS Expr1
FROM
RecordEntered AS A
LEFT OUTER JOIN
SoldInCountry AS B ON A.IdRecord = B.IdRecord
group by A.IdRecord, A.Qty
But I do not know how to go on.
I would like a query to show me how many pieces I still have in stock.
Like this:
A.Qty - (SUM(ISNULL(B.Qty, 0)) + SUM(ISNULL(C.Qty, 0)))
I wrote an example in SQL, but the goal is LINQ:
from a in _ctx.....
where .....
select...
thanks
It isn't easy to do a full outer join in LINQ (see my answer here: https://stackoverflow.com/a/43669055/2557128) but you don't need that to solve this:
var numInStock = from item in RecordEntered
select new {
item.Code,
Qty = item.Qty - (from sic in SoldInCountry where sic.IdRecord == item.IdRecord select sic.Qty).SingleOrDefault() -
(from soc in SoldOutCountry where soc.IdRecord == item.IdRecord select soc.Qty).SingleOrDefault()
};
I assumed there would only be one sold record of each type for an item, if there could be more than one, you would need to Sum the matching records:
var numInStock = from item in RecordEntered
select new {
item.Code,
Qty = item.Qty - (from sic in SoldInCountry where sic.IdRecord == item.IdRecord select sic.Qty).DefaultIfEmpty().Sum() -
(from soc in SoldOutCountry where soc.IdRecord == item.IdRecord select soc.Qty).DefaultIfEmpty().Sum()
};

joining multiple tables, then grouping and suming in linq

How could I get this SQL query right in LINQ?
SQL query:
select c.Name, sum(t.value)
from Categories c
join Items i on c.Id = i.CategoryId
join Transactions t on t.ItemId = i.Id
where datepart(YEAR, t.CreatedTime) = 2016
and datepart(MONTH, t.CreatedTime) = 2
group by c.Name
I've tried to do the same in LINQ and got this:
var query = from cat in _context.Categories
join item in _context.Items on cat.Id equals item.CategoryId
join trans in _context.Transactions on item.Id equals trans.ItemId
where trans.CreatedTime.Month == e.RowIndex && trans.CreatedTime.Year == 2016
group new { cat.Name, trans.Value } by cat.Name into g
select new
{
Value = g.Sum(entry => entry.Value)
};
But it seems to be totally wrong, besides not giving me back the category names, it returns wrong values for the sums as well.
I have three tables:
Categories with columns Id and Name
Items with columns Id, Name, CategoryId, LastValue, IsIncome,
Transactions with columns Id, ItemId, Value, CreatedTime, IsIncome

Calculated field returning same value SQL

I have an issue with the below sub-query:
(select AVG(retail)
from STOCK
where category = 'TOYOTA' or category = 'HONDA') as AVERAGE_SALE_PRICE
Entire query:
select
d.name, s.category,(select AVG(retail)
where category = 'TOYOTA' or category = 'HONDA') as AVERAGE_SALE_PRICE
from dealer d join stock s using (dealerID)
The issue is that this calculated field returns the same value for all the rows in the query, I understand that I may have add a GROUP BY but I am quite confused where...
Thanks for any help
Try this query:
select AVG(retail) as AVERAGE_SALE_PRICE, category
from STOCK
where category='TOYOTA' or category='HONDA'
group by category
Update.This should give you the desired results:
select
d.name,
s.category,
(select AVG(s.retail)
from stock s1
where s1.dealerID = s.dealerID
and (s1.category = 'TOYOTA' or s1.category = 'HONDA') as AVERAGE_SALE_PRICE
from dealer d
join stock s using (dealerID)

Using LINQ to get distinct items that do not join

I'm having problems running a LINQ query between two tables and returning an answer set that doesen't match.
TB_AvailableProducts
-Prod_ID
-Name
....
TB_Purchases
-Cust_ID
-Prod_ID
Is there a way to get all distinct products that a customer has not purchased by using 1 LINQ query, or do I have to be doing two separate queries, 1 for all products and 1 for purchased products, and compare the two?
This query will return all products, which do not have related record in purchases table.
int customerID = 1;
var query = from ap in context.TB_AvailableProducts
join p in context.TB_Purchases.Where(x => x.Cust_ID == customerID)
on ap.Prod_ID equals p.Prod_ID into g
where !g.Any()
select ap;
I don't think you need Distinct here if you don't have duplicated records in your products table.
Generated SQL query will look like:
SELECT ap.Prod_ID, ap.Name
FROM TB_AvailableProducts AS ap
WHERE NOT EXISTS (SELECT
1 AS C1
FROM TB_Purchases AS p
WHERE (1 = p.Cust_ID) AND (ap.Prod_ID = p.Prod_ID)
)

LINQ Joining 2 tables

I have two tables in the database one contains a list of all possible grocery values. For Example
Milk
Cheese
Bread
Meat
the second table contains Items from Grocery that are selected. For Example:
Milk
Cheese
I want a result that has all possible grocery items with Milk and Cheese selected.
Any ideas?
Here are the tables.
The GroceryList Table:
ID INT PK
Description Varchar(50)
The ShoppingList Table:
ID INT PK
GroceryListID int FK to GroceryList.ID
So the resulting Entity would be all items from GroceryList and if they exist in ShoppingList then selected is marked as true:
ShoppingList.ID
Grocerylists.Description
Selected
Based on understanding you can do something like this
//first get the list of product which satisfy your condition
var ids = (from p ShoppingList
select p.GroceryListID ).ToList();
//second filter the Grocery products by using contains
var myProducts = from p in GroceryList
where ids.Contains(p.ID)
Select p;
or
if you want to get info about join than this image would help you
Inner Join
Outer Join
Try to understand and which may help you to resolve your query
Edit: Still sounds like you want to do a left join. In your case:
var LINQResult = from g in Datacontext.GroceryList
from s in DataContext.ShoppingList
.Where(c=>c.ID == g.ID)
.DefaultIfEmpty()
select new {
g.ID,
g.Description,
s.ID // Will be null if not selected.
};
For more examples:
Left Join on multiple tables in Linq to SQL

Resources