how would you query this in linq? - linq

lets say i have 2 tables: products (just product ID and name) and sales (sale ID, product ID, amount, date)
now, given a start date and end date, i want to sum for every product its total sales amount in the given time frame
notice that naturally some products will just have zero sales
how should i write this query?

var products =
from p in mycontext.Products
select new
{
Product = p,
Sales = p.Sales
.Where(s=>s.StartDate > startDate && s.EndDate < endDate)
.Sum(s=>s.amount)
}

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()
};

Movie data set analysis using PIG

I have the following data set for a movie database:
Ratings: UserID, MovieID, Rating :: Movies: MovieID, Title :: Users: UserID, Gender, Age
Now I have to JOIN the above 3 datasets and determine which movie has the highest rating among females and lowest rating among males, and vice versa.
I have done the JOIN:
myusers = LOAD '/user/cloudera/movies/input/users.dat'
USING PigStorage(':')
AS (user:int, n1, gender:chararray, n2, age:int);
ratings = LOAD '/user/cloudera/movies/input/ratings.dat'
USING PigStorage(':')
AS (user:int, n1, movie:int, n2, rating:int);
movies = LOAD '/user/cloudera/movies/input/movies.dat'
USING PigStorage(':')
AS (movie:int,n1,title:chararray);
data = JOIN ratings BY user, myusers BY user;
data2= JOIN data BY ratings::movie, movies BY movie;
But after this I am running into many issues such as "ERROR 0: Scalar has more than one row in the output" when I try to print columns from data2. Any ideas to help me accomplish this task?
After the following step
data = JOIN ratings BY user, myusers BY user;
Create two datasets one for male and another for female by using gender as the filter.Order the dataset and get the max and min for both the datasets.
male = FILTER data by gender == 'M'; -- Use the gender value for male
female = FILTER data by gender == 'F';
m_max = LIMIT (ORDER male by rating DESC) 1;
f_max = LIMIT (ORDER female by rating DESC) 1;
m_min = LIMIT (ORDER male by rating ASC) 1;
f_min = LIMIT (ORDER female by rating ASC) 1;

Need help on oracle query

I have two oracle tables, table 1 contains students info and the second table contains student transaction details. Now I want an sql query to bring out the report of the transaction details for each student. eg student ID, name, amount, transaction date etc.
Note, a student can have many transactions, so I want a situation where by if student with ID 1 bought 3 items, in the result of the query I want to see student ID 1 and the sum of 3 items bought.
I don't want the student ID to repeat 3 times and the number of items bought.
Thanks
EDIT:
Here's the query I have so far:
select
distinct(s.spriden_id),
s.spriden_last_name,
s.spriden_first_name,
t.tbraccd_detail_code,
t.sum(tbraccd_amount),
t.tbraccd_term_code,
t.tbraccd_user,
t.TBRACCD_DATE
from SPRIDEN s, TBRACCD t
where s.spriden_pidm = t.tbraccd_pidm
and t.tbraccd_term_code = 201320
and t.tbraccd_desc = 'Misc Book Store Charges';
(The first table is SPRIDEN while the second table is TBRACCD)
You can use GROUP BY to group students, as below:
select
s.spriden_id,
sum(t.tbraccd_amount),
from SPRIDEN s, TBRACCD t
where s.spriden_pidm = t.tbraccd_pidm
and t.tbraccd_term_code = 201320
and t.tbraccd_desc = 'Misc Book Store Charges'
GROUP BY s.spriden_id;
MODIFIED VERSION to select all columns:
select
s.spriden_id,
t.tbraccd_entry_date,
t.tbraccd_term_code,
t.tbraccd_user,
sum(t.tbraccd_amount)
from SPRIDEN s, TBRACCD t
where s.spriden_pidm = t.tbraccd_pidm
and t.tbraccd_term_code = 201320
and t.tbraccd_desc = 'Misc Book Store Charges'
GROUP BY
s.spriden_id,
t.tbraccd_entry_date,
t.tbraccd_term_code,
t.tbraccd_user;

How to join two tables and make group by in 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
}
);

How to get the last element by date of each "type" in LINQ or TSQL

Imagine to have a table defined as
CREATE TABLE [dbo].[Price](
[ID] [int] NOT NULL,
[StartDate] [datetime] NOT NULL,
[Price] [int] NOT NULL
)
where ID is the identifier of an action having a certain Price. This price can be updated if necessary by adding a new line with the same ID, different Price, and a more recent date.
So with a set of a data like
ID StartDate Price
1 01/01/2009 10
1 01/01/2010 20
2 01/01/2009 10
2 01/01/2010 20
How to obtain a set like the following?
1 01/01/2010 20
2 01/01/2010 20
In SQL, there are several ways to say it. Here's one that uses a subquery:
SELECT *
FROM Price p
WHERE NOT EXISTS (
SELECT *
FROM Price
WHERE ID = p.ID
AND StartDate > p.StartDate
)
This translates fairly trivially to LINQ:
var q = from p in ctx.Price
where !(from pp in ctx.Price
where pp.ID == p.ID
&& pp.StartDate > p.StartDate
select pp
).Any()
select p;
Or should I say, I think it does. I'm not in front VS right now, so I can't verify that this is correct, or that LINQ will be able to convert it to SQL.
Minor quibble: Don't use the name ID to store a non-unique value (the type, in this case). It's confusing.
Assuming ID & StartDate will be unique:
SELECT p.ID, p.StartDate, p.Price
FROM Price p
JOIN
(
SELECT ID, MAX(StartDate) AS LatestDate
FROM Price
GROUP BY ID
) p2 ON p.ID = p2.ID AND p.StartDate = p2.LatestDate
Since you tagged your question with LINQ to SQL, here is an LINQ query to express what you want:
from price in db.Prices
group price by price.Id into group
let maxDateInGroup = group.Max(g => g.StartDate)
let maxDatePrice = group.First(g => g.StartDate == maxDateInGroup)
select
{
Id = group.Key,
StartDate = maxDatePrice.StartDate,
Price = maxDatePrice.Price
};

Resources