How to write the query using linq? - linq

How to write the query using linq?
SELECT
(SELECT SUM([quantity] * [price_usd])
FROM [vi].[dbo].[SALES]
WHERE [type_id] =1 and [date_id] in(200701,200702,200703,200704,200705,200706,200707,200708,200709,200710,200711,200712)) as y2007,
(SELECT SUM([quantity] * [price_usd])
FROM [vi].[dbo].[SALES]
WHERE [type_id] =1 and [date_id] in(200801,200802,200803,200804,200805,200806,200807,200808,200809,200810,200811,200812)) as y2008,
(SELECT SUM([quantity] * [price_usd])
FROM [vi].[dbo].[SALES]
WHERE [type_id] =1 and [date_id] in(200901,200902,200903,200904,200905,200906,200907,200908,200909,200910,200911,200912)) as y2009

What about that kind of query:
From s in Sales
where s.type_id == 1
group s by s.date_id.ToString().Substring(0,4) into g
select New { Year = g.Key, Sum = g.Sum(i => i.quantity * i.price_usd) }
I have no opportunity to try it on iPad, but the idea is clear and it should work.

Related

Order by in sub query using oracle

I tried to get value from sub query after ordering the records of it but the following occurred when execute the query :
ORA-00907: missing right parenthesis
The Query is :
select S.value , nvl((select D.value from D
join T on D.subID = t.SubID
where D.subid2 = s.subid2 and t.subid3 = s.subid3 and rownum = 1 order by t.id),0 ) value
from S
You can't have ORDER BY clause in a subquery.
See if something like this helps: use a CTE (as it looks somewhat nicer; could be a normal subquery, if you want) which calculates ordinal number for all rows, sorted by t.id column value. In outer (main) query, select row whose rn = 1 (which should act just like your ORDER BY t.id + rownum = 1).
WITH
temp
AS
(SELECT s.VALUE s_value,
d.VALUE d_value,
ROW_NUMBER () OVER (ORDER BY t.id) rn
FROM d
JOIN t ON d.subid = t.subid
JOIN s
ON s.subid2 = d.subid2
AND s.subid3 = t.subid3)
SELECT s_value, NVL (d_value, 0) d_value
FROM temp
WHERE rn = 1
If you are on Oracle 12c or higher, you can use the FETCH FIRST... clause.
SELECT S.VALUE,
NVL (( SELECT D.VALUE
FROM D JOIN T ON D.subID = t.SubID
WHERE D.subid2 = s.subid2 AND t.subid3 = s.subid3
ORDER BY t.id
FETCH FIRST 1 ROWS ONLY),
0) VALUE
FROM S

How to UPDATE from SELECT result where condition is ROWNUM?

I am having some problem creating update query based on select query with ROWNUM as WHERE condition.
I did experiments with these queries:
SELECT *
FROM
(SELECT ROWNUM, RVT.* FROM RVT)
WHERE RVT_ID IS NOT NULL;
This works, but
SELECT *
FROM
(SELECT ROWNUM, RVT.* FROM RVT) AS TEMP_TABLE1
WHERE TEMP_TABLE1.RVT_ID IS NOT NULL;
doesn't work.
What I want to achieve is this:
UPDATE REVIEW_T
SET RVT_RATING = 1
FROM (SELECT ROWNUM, RVT.* FROM RVT )
WHERE ROWNUM = 1;
Which does not work. Also,
UPDATE REVIEW_T
SET RVT_RATING = 1
FROM (SELECT ROWNUM, RVT.* FROM RVT) AS TEMP_TABLE
WHERE TEMP_TABLE.ROWNUM = 1;
doesn't work either.
What am I doing wrong?
I want to create 'index' 1,2,3,....600 for the all rows of one of my existing table
If that's so, then
UPDATE REVIEW_T SET RVT_RATING = rownum;

how to write this statement in linq to sql

SELECT TOP (5)
Sales.Product, Sales.Product_Price, COUNT(*) AS CNT,
Products.Category, Products.IMG_URL, Products.Rate_Avg
FROM
Sales
INNER JOIN
Products ON Sales.Product = Products.Product
GROUP BY
Sales.Product, Sales.Product_Price,
Products.Category, Products.IMG_URL, Products.Rate_Avg
HAVING
(COUNT(*) > 1)
ORDER BY CNT DESC
Most of that query has a 1-to-1 correspondence to the equivalent linq-to-sql expression. Though the TOP (5) part needs to be added to the end.
(from s in db.Sales
join p in db.Products on s.Product equals p.Product
group s by new { s.Product, s.Product_Price, p.Category, p.IMG_URL, p.Rate_Avg } into g
where g.Count() > 1
orderby g.Count() descending
select new
{
g.Key.Product,
g.Key.Product_Price,
CNT = g.Count(),
g.Key.Category,
g.Key.IMG_URL,
g.Key.Rate_Avg,
}).Take(5)

Distinct on one column in linq with joins

I know we can get distinct on one column using following query:
I know we can get distinct on one column using following query:
SELECT *
FROM (SELECT A, B, C,
ROW_NUMBER() OVER (PARTITION BY B ORDER BY A) AS RowNumber
FROM MyTable
WHERE B LIKE 'FOO%') AS a
WHERE a.RowNumber = 1
I have used similar sql query in my case where i am joining multiple tables but my project is in mvc4 and i need linq to entity equivalent of the same. Here is my code:
select * from
(
select fp.URN_No,
ROW_NUMBER() OVER
(PARTITION BY pdh.ChangedOn ORDER BY fp.CreatedOn)
as num,
fp.CreatedOn, pdh.FarmersName, pdh.ChangedOn, cdh.Address1, cdh.State, ich.TypeOfCertificate, ich.IdentityNumber, bdh.bankType, bdh.bankName,
pidh.DistrictId, pidh.PacsRegistrationNumber, idh.IncomeLevel, idh.GrossAnnualIncome
from MST_FarmerProfile as fp inner join PersonalDetailsHistories as pdh on fp.personDetails_Id = pdh.PersonalDetails_Id
inner join ContactDetailsHistories as cdh on fp.contactDetails_Id = cdh.ContactDetails_Id
inner join IdentityCertificateHistories as ich on fp.IdentityCertificate_Id = ich.IdentityCertificate_Id
inner join BankDetailsHistories as bdh on fp.BankDetails_Id = bdh.BankDetails_Id
left join PacInsuranceDataHistories as pidh on fp.PacsInsuranceData_Id = pidh.PacsInsuranceData_Id
left join IncomeDetailsHistories as idh on fp.IncomeDetails_Id = idh.IncomeDetails_Id
where URN_No in(
select distinct MST_FarmerProfile_URN_No from PersonalDetailsHistories where MST_FarmerProfile_URN_No in(
select URN_No from MST_FarmerProfile where (CreatedOn>=#fromDate and CreatedOn<= #toDate and Status='Active')))
)a where a.num=1
Use this linq query after getting result from sql. p.ID is be your desire distinct column name
List<Person> distinctRecords = YourResultList
.GroupBy(p => new { p.ID})
.Select(g => g.First())
.ToList();

CROSS APPLY too slow for running total - TSQL

Please see my code below as it is running too slowly with the CROSS APPLY.
How can I remove the CROSS APPLY and add something else that will run faster?
Please note I am using SQL Server 2008 R2.
;WITH MyCTE AS
(
SELECT
R.NetWinCURRENCYValue AS NetWin
,dD.[Date] AS TheDay
FROM
dimPlayer AS P
JOIN
dbo.factRevenue AS R ON P.playerKey = R.playerKey
JOIN
dbo.vw_Date AS dD ON Dd.dateKey = R.dateKey
WHERE
P.CustomerID = 12345)
SELECT
A.TheDay AS [Date]
,ISNULL(A.NetWin, 0) AS NetWin
,rt.runningTotal AS CumulativeNetWin
FROM MyCTE AS A
CROSS APPLY (SELECT SUM(NetWin) AS runningTotal
FROM MyCTE WHERE TheDay <= A.TheDay) AS rt
ORDER BY A.TheDay
CREATE TABLE #temp (NetWin money, TheDay datetime)
insert into #temp
SELECT
R.NetWinCURRENCYValue AS NetWin
,dD.[Date] AS TheDay
FROM
dimPlayer AS P
JOIN
dbo.factRevenue AS R ON P.playerKey = R.playerKey
JOIN
dbo.vw_Date AS dD ON Dd.dateKey = R.dateKey
WHERE
P.CustomerID = 12345;
SELECT
A.TheDay AS [Date]
,ISNULL(A.NetWin, 0) AS NetWin
,SUM(B.NetWin) AS CumulativeNetWin
FROM #temp AS A
JOIN #temp AS B
ON A.TheDay >= B.TheDay
GROUP BY A.TheDay, ISNULL(A.NetWin, 0);
Here https://stackoverflow.com/a/13744550/613130 it's suggested to use recursive CTE.
;WITH MyCTE AS
(
SELECT
R.NetWinCURRENCYValue AS NetWin
,dD.[Date] AS TheDay
,ROW_NUMBER() OVER (ORDER BY dD.[Date]) AS RN
FROM dimPlayer AS P
JOIN dbo.factRevenue AS R ON P.playerKey = R.playerKey
JOIN dbo.vw_Date AS dD ON Dd.dateKey = R.dateKey
WHERE P.CustomerID = 12345
)
, MyCTERec AS
(
SELECT C.TheDay AS [Date]
,ISNULL(C.NetWin, 0) AS NetWin
,ISNULL(C.NetWin, 0) AS CumulativeNetWin
,C.RN
FROM MyCTE AS C
WHERE C.RN = 1
UNION ALL
SELECT C.TheDay AS [Date]
,ISNULL(C.NetWin, 0) AS NetWin
,P.CumulativeNetWin + ISNULL(C.NetWin, 0) AS CumulativeNetWin
,C.RN
FROM MyCTERec P
INNER JOIN MyCTE AS C ON C.RN = P.RN + 1
)
SELECT *
FROM MyCTERec
ORDER BY RN
OPTION (MAXRECURSION 0)
Note that this query will work if you have 1 record == 1 day! If you have multiple records in a day, the results will be different from the other query.
As I said here, if you want really fast calculation, put it into temporary table with sequential primary key and then calculate rolling total:
create table #Temp (
ID bigint identity(1, 1) primary key,
[Date] date,
NetWin decimal(29, 10)
)
insert into #Temp ([Date], NetWin)
select
dD.[Date],
sum(R.NetWinCURRENCYValue) as NetWin,
from dbo.dimPlayer as P
inner join dbo.factRevenue as R on P.playerKey = R.playerKey
inner join dbo.vw_Date as dD on Dd.dateKey = R.dateKey
where P.CustomerID = 12345
group by dD.[Date]
order by dD.[Date]
;with cte as (
select T.ID, T.[Date], T.NetWin, T.NetWin as CumulativeNetWin
from #Temp as T
where T.ID = 1
union all
select T.ID, T.[Date], T.NetWin, T.NetWin + C.CumulativeNetWin as CumulativeNetWin
from cte as C
inner join #Temp as T on T.ID = C.ID + 1
)
select C.[Date], C.NetWin, C.CumulativeNetWin
from cte as C
order by C.[Date]
I assume that you could have duplicates dates in the input, but don't want duplicates in the output, so I grouped data before puting it into the table.

Resources