I really need advice on the below, trying to use DB function getpreviousorders..
SELECT o1.* FROM "sample"."order" o1 JOIN "sample".patient p1 ON o1.patient_id = p1.id
WHERE o1.sample_id != _sampleId AND p1.mrn = _mrn
AND ((o1.collection_date is not null AND o1.collection_date >= _createdDate)
OR (o1.collection_date is null AND o1.receipt_date is not null
AND o1.receipt_date >= _createdDate))
UNION
(SELECT o2.* FROM "sample"."order" o2 JOIN "sample".patient p2 ON o2.patient_id = p2.id
WHERE (o2.status = 1 or o2.status = 2 OR o2.status = 3) AND o2.sample_id != _sampleId
AND p2.mrn = _mrn
AND ((o2.collection_date is not null AND o2.collection_date < _createdDate)
OR (o2.collection_date is null AND o2.receipt_date is not null
AND o2.receipt_date < _createdDate)) ORDER by created_date DESC LIMIT 1)
ORDER by collection_date DESC, receipt_date DESC, created_date DESC;
Total time to get 199 previous order is 2628ms, and all most time taken for funciton findPreviousOrders: 2535ms
Analyze Query & Code Snippets !!!
I can do this really easily in SQL but I can't translate it into LINQ.
The SQL:
SELECT EmployeeId
,YEAR(DistributionDate) AS DistributionYear
,SUM(SalesLocal * FX.ExchangeRate) AS TotalDistributions
FROM Distributions AS DD INNER JOIN FiscalPeriod AS FP ON DD.DistributionDate BETWEEN FP.StartDate AND FP.EndDate
INNER JOIN FXRates AS FX ON FP.FiscalPeriodId = FX.FiscalPeriodId AND FX.FromCurrencyId = DD.CurrencyId AND FX.ToCurrencyId = 'USD'
GROUP BY EmployeeId, YEAR(DistributionDate)
ORDER BY EmployeeId, DistributionYear
This is my broken attempt at translation:
var pointList = (from dd in db.Distributions
join e in db.Employee on dd.EmployeeId equals e.EmployeeId
join fp in db.FiscalPeriod.Where(p => dd.DistributionDate >= p.StartDate && dd.DistributionDate <= p.EndDate)
join fx in db.Fxrates on (fp.FiscalPeriodId equals fx.FiscalPeriodId) && (fx.FromCurrencyId equals dd.CurrencyId) && (fx.ToCurrencyId equals "USD")
group by dd.EmployeeId && dd.DistributionDate.Year
select new Point<int, decimal?>
{
X = dd.DistributionDate.Year,
Y = dd.Sum(dd.SalesLocal * fx.ExchangeRate)
}).ToList();
Visual Studio complains first that dd is not declared and then really complains once it reaches the join to Fxrates.
I think this may be close to what you want:
var pointList = (from dd in db.Distributions
join e in db.Employee on dd.EmployeeId equals e.EmployeeId
from fp in db.FiscalPeriod.Where(p => dd.DistributionDate >= p.StartDate && dd.DistributionDate <= p.EndDate)
from fx in db.Fxrates.Where(fx2 => fp.FiscalPeriodId == fx2.FiscalPeriodId && fx2.FromCurrencyId == dd.CurrencyId && fx2.ToCurrencyId == "USD")
group new { dd, fx } by new { dd.EmployeeId, dd.DistributionDate.Year } into distGroup
select new
{
X = distGroup.Key.Year,
Y = distGroup.Sum(d => d.dd.SalesLocal * d.fx.ExchangeRate)
}).ToList();
I have this select which works in T-SQL, but need to convert to Entity Framework. How can I use case in Entity Framework?
select
*
from
Contrato c
where
c.QtdParcelasFalta > 0
and (case
when c.DiaEspecificoMarcar = 1
then c.DiaEspecifico
when c.DiaEspecificoMarcar = 0
then (select convert(int, substring(DataCobranca, 2, 2))
from Contrato
where Contrato.Id = c.Id) -
(select e.DataProcessamentoNota
from Contrato t
inner join PedidoVenda p on p.id = t.PedidoVendaId
inner join Empresas e on p.EmpresaID = e.Id
where p.id = t.PedidoVendaId
and t.id = c.Id and p.EmpresaID = 1)
end) = (SELECT DAY(GETDATE()))
I tried it like this, but it didn't work out, did not pass the correct values, because I'm not aware of pass to Entity Framework:
var contrato = db.Contrato
.Include(a => a.PedidoVenda)
.Include(a => a.Cliente)
.Where(a => a.PedidoVenda.EmpresaID == model.EmpresaID
&& a.Cancelado == false
&& a.DiaEspecificoMarcar == true
&& a.DiaEspecifico == int.Parse(DateTime.Now.ToString("dd")) ||
(int.Parse(a.DataCobranca.Substring(1, 2)) - a.PedidoVenda.Empresa.DataProcessamentoNota)
== int.Parse(DateTime.Now.ToString("dd"))
).ToList();
You are actually on the right track. You just need to add when conditions to your lef and right conditions like this:
var contrato = db.Contrato.Include(a => a.PedidoVenda).Include(a => a.Cliente).Where
(a => a.PedidoVenda.EmpresaID == model.EmpresaID && a.Cancelado == false &&
a.DiaEspecificoMarcar == false && a.DiaEspecifico == int.Parse(DateTime.Now.ToString("dd")) ||
( a.DiaEspecificoMarcar == true && int.Parse(a.DataCobranca.Substring(1, 2)) - a.PedidoVenda.Empresa.DataProcessamentoNota)
== int.Parse(DateTime.Now.ToString("dd"))
).ToList();
I also suggest you use DateTime.Now from a variable to be sure both int.Parse gets the same input
I got this figured out.
No need to answer.
The system says I have to wait 8 hours before answering my own questions. But for now the answer is below:
Here is the answer:
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
join q in Quotes
on h.QuoteID equals q.QuoteID
join a in Agencies
on q.AgencyID equals a.AgencyID
where q.Status == "Inforce" &&
q.LOB == "Vacant" &&
q.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
a.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
MaxHistoryID = g.Max (x => x.h.HistoryID),
comment = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.Comment).FirstOrDefault()
}).ToList();
The key code was:
comment = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.Comment).FirstOrDefault()
We are in the process of converting SQL / Stored Procedures to LINQ to Entities statements. And I can’t figure out the proper syntax for a sub select.
Currently I am converting this SQL:
declare #startDate DateTime
set #startDate = DATEADD(DD, -30, GETDATE())
select * from history where historyid in(
select MAX(h.historyid) as HistoryId
from History h (nolock)
inner join Quote q (nolock) on h.QuoteID = q.QuoteID
inner join Agency (nolock) a on q.AgencyID = a.AgencyID
inner join DC_PLT_EntityRoles er (nolock) on a.AgencyID = er.EntityID
inner join DC_PLT_Roles (nolock) r on er.RoleID = r.RoleID
where
q.Status = 'Inforce'
and q.LOB = 'Vacant'
and q.EffectiveDate > #startDate
and h.Deleted is null --
and h.DeprecatedBy is null --
and h.TransactionStatus = 'Committed'
and r.Name = 'Wholesaler'
group by h.PolicyNumber)
As you can see the code above is made up of two select statements. The main select (select * from history).. And a filter select (select MAX(h.historyid)…)
I got the filter select working (See below):
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
join q in Quotes
on h.QuoteID equals q.QuoteID
join a in Agencies
on q.AgencyID equals a.AgencyID
where q.Status == "Inforce" &&
q.LOB == "Vacant" &&
q.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
a.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
MaxHistoryID = g.Max (x => x.h.HistoryID)
}).ToList();
However I can’t figure out the proper syntax to set up the main select. (Basically getting the records from the History table using the HistoryID from the filter select.)
Any help would be appreciated.
Thanks for your help.
I figured it out, here is the code:
var startDate = DateTime.Today.AddDays(-30);
var results = (from h in Histories
.Include("Quote")
.Include("Quote.Agency")
where h.Quote.Status == "Inforce" &&
h.Quote.LOB == "Vacant" &&
h.Quote.EffectiveDate > startDate &&
h.Deleted == null &&
h.DeprecatedBy == null &&
h.TransactionStatus == "Committed" &&
h.Quote.Agency.DC_PLT_Roles.Any(r => r.Name == "Wholesaler")
group new {h} by new {h.PolicyNumber} into g
select new {
XMLData = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.XMLData).FirstOrDefault()
}).ToList();
The key logic is:
select new {
XMLData = (from h2 in Histories
where h2.HistoryID == g.Max (x => x.h.HistoryID)
select h2.XMLData).FirstOrDefault()
}).ToList();
Gotta love the Nested Query
I have select, iside select have 2 column. This column must be filled from same select, but I don't want use select twice for it. Is it possoble use select 1 time and after that set second column value from first?
Example:
insert into #temptable from
select
a = (select aa from table1 where quantity > 5)
b = (select aa from table1 where quantity > 5)
I need:
insert into #temptable from
select
a = (select aa from table1 where quantity > 5)
b = {value from a}
Update. I wrote bad example, I need set to BalancePrediction1 and BalancePrediction2 value from Balance
INSERT #tmpBalances
SELECT PA.ContractId AS 'ContractId',
Con.Name AS 'ContractName',
Bal.PortfolioAccountId AS 'PortfolioAccountId',
PA.Name AS 'PortfolioAccountName',
RA.GeneralId AS 'RegisterAccountGeneralId',
Bal.BalanceTypeId AS 'BalanceTypeId',
Bt.Name AS 'BalanceTypeName',
Bt.Type AS 'BalanceTypeType',
Bal.BalanceTimeType AS 'BalanceTimeType',
Bal.InstrumentId AS 'InstrumentId',
Ins.Name AS 'InstrumentName',
Ins.GeneralId AS 'InstrumentGeneralId',
(Bal.Balance -
(
SELECT COALESCE(SUM(Mov.Amount), 0)
FROM trd.Movements AS Mov
WHERE
Bal.InstrumentId = Mov.InstrumentId AND
Bal.PortfolioAccountId = Mov.PortfolioAccountId AND
Bal.BalanceTypeId = Mov.BalanceTypeId AND
Bal.BalanceTimeType = Mov.BalanceTimeType AND
DateDiff(DAY, #Date, Mov.Date) > 0 AND
-- Currency může být null a NULL = NULL nejde
COALESCE(Bal.CurrencyId, -1) = COALESCE(Mov.CurrencyId, -1)
)
) as Balance,
Balance AS 'BalancePrediction1',
Balance AS 'BalancePrediction2',
Bal.CurrencyId AS 'CurrencyId',
Ccy.Code AS 'CurrencyCode',
PA.PositionServiceType 'PositionServiceType',
Ccy.Name 'CurrencyName',
S.Nominal AS 'Nominal',
S.NominalCurrencyId AS 'NominalCurrencyId',
trd.GetCurrencyCode(S.NominalCurrencyId) AS 'NominalCurrencyCode'
FROM trd.Balances AS Bal
JOIN trd.PortfolioAccounts AS PA ON PA.Id = Bal.PortfolioAccountId
JOIN trd.Contracts AS Con ON Con.Id = PA.ContractId
JOIN trd.RegisterAccounts AS RA ON RA.Id = PA.RegisterAccountId
JOIN trd.BalanceTypes AS Bt ON Bt.Id = Bal.BalanceTypeId
JOIN trd.Instruments AS Ins ON Ins.Id = Bal.InstrumentId
LEFT OUTER JOIN trd.Currencies AS Ccy ON Ccy.Id = Bal.CurrencyId
LEFT JOIN trd.SecuritiesView S ON s.Id = Ins.Id AND DateDiff(d, S.ValidFrom, #Date) >= 0 AND (S.ValidTo IS NULL OR DateDiff(d, S.ValidTo, #Date) < 0)
AND S.InstrumentInstrumentTypePriceUnit = 1
You could do an update to the table variable after the insert.
update #tmpBalances
set BalancePrediction1 = Balance,
BalancePrediction2 = Balance
Or you can use cross apply to calculate the sum.
INSERT #tmpBalances
SELECT PA.ContractId AS 'ContractId',
Con.Name AS 'ContractName',
Bal.PortfolioAccountId AS 'PortfolioAccountId',
PA.Name AS 'PortfolioAccountName',
RA.GeneralId AS 'RegisterAccountGeneralId',
Bal.BalanceTypeId AS 'BalanceTypeId',
Bt.Name AS 'BalanceTypeName',
Bt.Type AS 'BalanceTypeType',
Bal.BalanceTimeType AS 'BalanceTimeType',
Bal.InstrumentId AS 'InstrumentId',
Ins.Name AS 'InstrumentName',
Ins.GeneralId AS 'InstrumentGeneralId',
(Bal.Balance - Mov.SumAmount) AS Balance,
(Bal.Balance - Mov.SumAmount) AS 'BalancePrediction1',
(Bal.Balance - Mov.SumAmount) AS 'BalancePrediction2',
Bal.CurrencyId AS 'CurrencyId',
Ccy.Code AS 'CurrencyCode',
PA.PositionServiceType 'PositionServiceType',
Ccy.Name 'CurrencyName',
S.Nominal AS 'Nominal',
S.NominalCurrencyId AS 'NominalCurrencyId',
trd.GetCurrencyCode(S.NominalCurrencyId) AS 'NominalCurrencyCode'
FROM trd.Balances AS Bal
JOIN trd.PortfolioAccounts AS PA ON PA.Id = Bal.PortfolioAccountId
JOIN trd.Contracts AS Con ON Con.Id = PA.ContractId
JOIN trd.RegisterAccounts AS RA ON RA.Id = PA.RegisterAccountId
JOIN trd.BalanceTypes AS Bt ON Bt.Id = Bal.BalanceTypeId
JOIN trd.Instruments AS Ins ON Ins.Id = Bal.InstrumentId
LEFT OUTER JOIN trd.Currencies AS Ccy ON Ccy.Id = Bal.CurrencyId
LEFT JOIN trd.SecuritiesView S ON s.Id = Ins.Id AND DateDiff(d, S.ValidFrom, #Date) >= 0 AND (S.ValidTo IS NULL OR DateDiff(d, S.ValidTo, #Date) < 0)
AND S.InstrumentInstrumentTypePriceUnit = 1
CROSS APPLY (SELECT COALESCE(SUM(Mov.Amount), 0)
FROM trd.Movements AS Mov
WHERE
Bal.InstrumentId = Mov.InstrumentId AND
Bal.PortfolioAccountId = Mov.PortfolioAccountId AND
Bal.BalanceTypeId = Mov.BalanceTypeId AND
Bal.BalanceTimeType = Mov.BalanceTimeType AND
DateDiff(DAY, #Date, Mov.Date) > 0 AND
-- Currency může být null a NULL = NULL nejde
COALESCE(Bal.CurrencyId, -1) = COALESCE(Mov.CurrencyId, -1)
) Mov(SumAmount)
SELECT aa AS a, aa AS b
FROM table1
WHERE quantity > 5
One way;
;with T (value) as (
select aa from table1 where quantity > 5
)
insert into #temptable
select value, value from T