Appropriate if somebody could help us to optimize below query
As per execution plane it seems the else part sub query is always executing, irrespective of conditions.
Won't CASE be short circuited? Why is it executing, even though it is not necessary?
IF OBJECT_ID('#Calculation') IS NOT NULL
DROP TABLE #Calculation;
SELECT
Result.IdDeckungsbeitrag,
Result.wert AS Wert,
REPLACE(#Formula, '<#PackagingCosts> ', Result.wert) AS Kalkulation
INTO
#Calculation
FROM
(SELECT
deck.IdDeckungsbeitrag,
CASE
WHEN lp.ID_VERPACKUNG_2 IS NULL
AND lp.ID_VERPACKUNG_3 IS NULL
THEN vg.VERPACKUNGSKOSTEN_PRO_EINHEIT * deck.Menge
ELSE
(
SELECT SUM(temp.me) * vg.VERPACKUNGSKOSTEN_PRO_EINHEIT
FROM
(
SELECT SUM(gv.MENGE) AS me
FROM dbo.KUNDENRECHNUNG_POSITION krp
LEFT JOIN dbo.LIEFERSCHEIN_POSITION lp
ON lp.ID_LIEFERSCHEIN_POSITION = krp.ID_LIEFERSCHEIN_POSITION
LEFT JOIN dbo.GEBINDE_VERLADEN gv
ON gv.ID_LIEFERSCHEIN_POSITION = lp.ID_LIEFERSCHEIN_POSITION
LEFT JOIN dbo.MATERIAL_BESTAND mb
ON mb.ID_MATERIAL_BESTAND = gv.ID_MATERIAL_BESTAND
LEFT JOIN dbo.MATERIAL_GEBINDE mg
ON mg.ID_MATERIAL_BESTAND = mg.ID_MATERIAL_BESTAND
WHERE mg.CHARGE_NUMMER = deck.Charge
GROUP BY mg.ID_VERPACKUNG
) temp
)
END AS wert
FROM #DeckungsbeitragCalculationPositions_TVP deck
LEFT JOIN dbo.KUNDENRECHNUNG_POSITION krp
ON krp.ID_KUNDENRECHNUNG_POSITION = deck.IdDeckungsbeitrag
LEFT JOIN dbo.LIEFERSCHEIN_POSITION lp
ON lp.ID_LIEFERSCHEIN_POSITION = krp.ID_LIEFERSCHEIN_POSITION
LEFT JOIN dbo.VERPACKUNG vg
ON vg.ID_VERPACKUNG = lp.ID_VERPACKUNG_1
WHERE deck.IdMandant = #Id_Mandant
) Result;
Don't think of it as short-circuit or not. That's a procedural code mindset rather than a set-based mindset.
In SQL, the actual "execution" happens in the realm of table or index scans and seeks, hash matches, sorts, and the like. Pull data from different tables into a working set that will eventually produce the desired relational result.
Not seeing any real or projected execution plan, in this case (no pun intended), I suspect the query optimizer decided it was most efficient to first produce this result set in memory:
SELECT mg.ID_VERPACKUNG, mg.CHARGE_NUMMER, SUM(gv.MENGE) AS me
FROM dbo.KUNDENRECHNUNG_POSITION krp
LEFT JOIN dbo.LIEFERSCHEIN_POSITION lp
ON lp.ID_LIEFERSCHEIN_POSITION = krp.ID_LIEFERSCHEIN_POSITION
LEFT JOIN dbo.GEBINDE_VERLADEN gv
ON gv.ID_LIEFERSCHEIN_POSITION = lp.ID_LIEFERSCHEIN_POSITION
LEFT JOIN dbo.MATERIAL_BESTAND mb
ON mb.ID_MATERIAL_BESTAND = gv.ID_MATERIAL_BESTAND
LEFT JOIN dbo.MATERIAL_GEBINDE mg
ON mg.ID_MATERIAL_BESTAND = mg.ID_MATERIAL_BESTAND
GROUP BY mg.ID_VERPACKUNG, mg.CHARGE_NUMMER
This is the subquery from the ELSE clause, minus the WHERE clause conditions and with additional info added to the SELECT to make the match more effective. If the query optimizer can't be confident of meeting the WHEN clause a high percentage of the time, it might believe producing this larger ELSE set once to match against as needed is more efficient. Put another way, if it thinks it will have to run that subquery a lot anyway, it may try to pre-load it for all possible data.
We don't know enough about your database to suggest real solutions, but indexing around the ID_VERPACKUNG_2, ID_VERPACKUNG_3, and CHARGE_NUMMER fields might help. You might also be able to use a CTE, temp table, or table variable to help Sql Server to a better job of caching this data just once.
If the conditions of where are not met then the else will become active. If this is always the case then you would expect the following to return no rows:
select *
FROM #DeckungsbeitragCalculationPositions_TVP deck
LEFT JOIN dbo.KUNDENRECHNUNG_POSITION krp ON krp.ID_KUNDENRECHNUNG_POSITION = deck.IdDeckungsbeitrag
LEFT JOIN dbo.LIEFERSCHEIN_POSITION lp ON lp.ID_LIEFERSCHEIN_POSITION = krp.ID_LIEFERSCHEIN_POSITION
WHERE lp.ID_VERPACKUNG_2 IS NULL
AND lp.ID_VERPACKUNG_3 IS NULL
select sum(l.coins) - sum(t.coins) as total
from luxx_getaway_2016_coins l
join thrive_rewards_redeemed t
on l.consid = t.guideid
where l.consid = 24969 and t.harvestyear = 1516
Hello all. I am attempting to grab an updated total using the query above. The problem I'm having is that the total of these sums totals out to well above what it should be. I'm unsure of what I'm doing wrong. We're using Azure SQL Database and I've used RazorSQL and SSMS 2012 to run this query with identical results. Any help is appreciated. Please feel free to ask for clarification.
A simple solution to your duplication problem:
Select
(select sum(l.coins)
from luxx_getaway_2016_coins l
where l.consid = 24969)
-
(select sum(t.coins)
from thrive_rewards_redeemed t
where t.guideid = 24969
and t.harvestyear = 1516)
For the more general case:
; With A as (select consid, sum(l.coins) as TotA
from luxx_getaway_2016_coins l
group by consid)
, B as (select guideid, sum(t.coins) as TotB
from thrive_rewards_redeemed t
where t.harvestyear = 1516
group by guideID)
Select a.consid, TotA - TotB as Total
from A
inner join B
on a.Consid = b.GuideID
I did ask this question before but deleted the post.
Here is my question: I have a table in SQL Server with multiple events in the table, I am trying to filter on the events and the datetime between the events on a certain X min.
I need help with T-SQL queries.
What can use use to do the following (any links will be appreciated):
take event_id and datetime of device, compare to a list of other event_id's to see if there are any other events withing the last 24 min for that device.
What would work for me? Nested queries? Where clause? CTE?
I have tried 6 queries but not getting the result I need, do I use (max) datetime and then compare on event_ID's?
I know this is not much but any help or links would be appreciated....
On Request (Full Query no changes)
1.
SELECT A.[Unit_id]
,A.[TransDate]
,A.[event_id]
,A.[event_msg]
,B.[TransDate]
,B.[event_id]
,B.[event_msg]
FROM
(Select
A.[Unit_id]
,MAX(A.[TransDate]) AS Transdate
,A.[event_id]
,A.[event_msg]
FROM [JammingEvents].[dbo].[EventLogExtended] AS A
WHERE event_id = '345'
GROUP BY A.[Unit_id]
,A.[event_id]
,A.[event_msg]
) AS A
INNER JOIN
(SELECT
B.[Unit_id]
,MAX(B.[TransDate]) AS Transdate
,B.[event_id]
,B.[event_msg]
FROM [JammingEvents].[dbo].[EventLogExtended] AS B
WHERE B.event_id = '985'
GROUP BY B.[Unit_id]
,B.[event_id]
,B.[event_msg]
) AS B
ON
A.Unit_id = B.Unit_id
WHERE (B.TransDate BETWEEN DATEADD(MINUTE,-24,A.Transdate) AND DATEADD(MINUTE,24,A.Transdate))
this works but only if you compare 2 event Id's. the problem is i need to do this on a bulk scale.
2.
SET NOCOUNT ON
GO
SELECT MAX(ELE.Transdate) AS Transdate
,ELE.[Unit_id]
,ELE.[event_id]
,ELE.[event_msg]
,ELE.[Latitude]
,ELE.[Longitude]
,ELE.[date_ack]
,ELE.[user_id_ack]
,ELE.[date_closed]
,ELE.[user_id_closed]
,ELE.[action]
,ELE.[EventSeqNo]
,ELE.[MsgSeqNo]
,ELE.[Speed]
,ELE.[Heading]
,ELE.[Status1]
,ELE.[Status2]
,ELE.[GeoLocation]
,ELE.[Reg_No]
,ELE.[Company]
,ELE.[Fleet_Code]
,ELE.[IgnStatus]
,ELE.[comboActioned]
FROM
[JammingEvents].[dbo].[EventLogExtended] ELE
INNER JOIN
(
SELECT
F.Transdate ,F.[Unit_id] ,F.[event_id] ,F.[event_msg] ,F.[Latitude] ,F.[Longitude] ,F.[date_ack] ,F.[user_id_ack]
,F.[date_closed] ,F.[user_id_closed] ,F.[action] ,F.[EventSeqNo] ,F.[MsgSeqNo] ,F.[Speed] ,F.[Heading] ,F.[Status1]
,F.[Status2] ,F.[GeoLocation] ,F.[Reg_No] ,F.[Company] ,F.[Fleet_Code] ,F.[IgnStatus] ,F.[comboActioned]
FROM [JammingEvents].[dbo].[EventLogExtended] AS F
WHERE
F.event_id IN
('302'
,'303'
,'304'
,'305'
,'309'
,'340'
,'341'
,'345'
,'962'
,'963'
,'973'
,'974'
,'975'
,'976'
,'985'
,'987'
,'989'
,'C220'
,'C222'
,'C224'
,'C227'
,'C228')
) AS A
ON
ELE.Unit_id = A.Unit_id
INNER JOIN
(
SELECT
G.Transdate ,G.[Unit_id] ,G.[event_id] ,G.[event_msg] ,G.[Latitude] ,G.[Longitude] ,G.[date_ack]
,G.[user_id_ack] ,G.[date_closed] ,G.[user_id_closed] ,G.[action] ,G.[EventSeqNo] ,G.[MsgSeqNo] ,G.[Speed] ,G.[Heading]
,G.[Status1] ,G.[Status2] ,G.[GeoLocation] ,G.[Reg_No] ,G.[Company] ,G.[Fleet_Code] ,G.[IgnStatus] ,G.[comboActioned]
FROM [JammingEvents].[dbo].[EventLogExtended] AS G
WHERE
G.event_id = '345'
) AS B
ON
A.Unit_id = B.Unit_id
WHERE (ELE.TransDate BETWEEN DATEADD(MINUTE,-24,A.Transdate) AND DATEADD(MINUTE,24,A.Transdate))
AND
(ELE.event_id IN
(
'302'
,'303'
,'304'
,'305'
,'309'
,'340'
,'341'
,'345'
,'962'
,'963'
,'973'
,'974'
,'975'
,'976'
,'985'
,'987'
,'989'
,'C220'
,'C222'
,'C224'
,'C227'
,'C228'
))
AND
(ELE.action = '0')
GROUP BY ELE.TransDate
,A.Unit_id
,ELE.[Unit_id]
,ELE.[event_id]
,ELE.[event_msg]
,ELE.[Latitude]
,ELE.[Longitude]
,ELE.[date_ack]
,ELE.[user_id_ack]
,ELE.[date_closed]
,ELE.[user_id_closed]
,ELE.[action]
,ELE.[EventSeqNo]
,ELE.[MsgSeqNo]
,ELE.[Speed]
,ELE.[Heading]
,ELE.[Status1]
,ELE.[Status2]
,ELE.[GeoLocation]
,ELE.[Reg_No]
,ELE.[Company]
,ELE.[Fleet_Code]
,ELE.[IgnStatus]
,ELE.[comboActioned]
ORDER BY ELE.TransDate, ELE.Unit_id DESC
so far this got me the closest but i have no idea what to do, i am very poor with SQL syntax and writing queries.
You could use an exists subquery to demand that there was another event for the same device within the preceeding 24 minutes:
select *
from Events e1
where exists
(
select *
from Events e2
where e2.Device_ID = e1.Device_ID
and e2.event_dt between
dateadd(minute, e1.event_dt, -24)
and e1.event_dt
)
Self join should work as well:
SELECT *, DATEDIFF(minute,b.transdate,a.transdate) diff FROM EventLogWxtended a
JOIN eventLogExtended b
ON (a.unit_id=b.unit_id AND b.transdate<a.transdate
AND DATEDIFF(minute,b.transdate,a.transdate)<24)
This query has been keeping me busy for the last couple of days. I tried to rewrite it with different ideas but I keep having the same problem. To simplify the problem I put part of my query in a view, this view returns 23 records. Using a left join I would like to add fields coming from the table tblDatPositionsCalc to these 23 records. As you can see I have an additional condition on the tblDatPositionsCalc in order to only consider the most recent records. With this condition it would return 21 records. The join should be on two fields together colAccount and colId.
I simply want the query to return the 23 records from the view and where possible have the information from tblDatPositionsCalc. There is actually only 2 records in the view without corresponding id and account in tblDatPositionsCalc, that means out of the 23 records only 2 will have missing values in the fields coming from the table tblDatPositionsCalc.
The problem with my query is that it only returns the 21 records from tblDatPositionsCalc. I don't understand why. I tried to move the condition on date in just after the JOIN condition but that did not help.
SELECT TOP (100) PERCENT
dbo.vwCurrPos.Account,
dbo.vwCurrPos.Id,
dbo.vwCurrPos.TickerBB,
dbo.vwCurrPos.colEquityCode,
dbo.vwCurrPos.colType,
dbo.vwCurrPos.colCcy,
dbo.vwCurrPos.colRegion,
dbo.vwCurrPos.colExchange,
dbo.vwCurrPos.[Instr Type],
dbo.vwCurrPos.colMinLastDay,
dbo.vwCurrPos.colTimeShift,
dbo.vwCurrPos.Strike,
dbo.vwCurrPos.colMultiplier,
dbo.vwCurrPos.colBetaVol,
dbo.vwCurrPos.colBetaEq,
dbo.vwCurrPos.colBetaFloor,
dbo.vwCurrPos.colBetaCurv,
dbo.vwCurrPos.colUndlVol,
dbo.vwCurrPos.colUndlEq,
dbo.vwCurrPos.colUndlFut,
tblDatPositionsCalc_1.colLots,
dbo.vwCurrPos.[Open Positions],
dbo.vwCurrPos.colListMatShift,
dbo.vwCurrPos.colStartTime,
tblDatPositionsCalc_1.colPrice,
tblDatPositionsCalc_1.colMktPrice,
dbo.vwCurrPos.colProduct,
dbo.vwCurrPos.colCalendar,
CAST(dbo.vwCurrPos.colExpiry AS DATETIME) AS colExpiry,
dbo.vwCurrPos.colEndTime,
CAST(tblDatPositionsCalc_1.colDate AS datetime) AS colDate,
dbo.vwCurrPos.colFund,
dbo.vwCurrPos.colExchangeTT,
dbo.vwCurrPos.colUserTag
FROM dbo.vwCurrPos
LEFT OUTER JOIN dbo.tblDatPositionsCalc AS tblDatPositionsCalc_1
ON tblDatPositionsCalc_1.colId = dbo.vwCurrPos.Id
AND tblDatPositionsCalc_1.colAccount = dbo.vwCurrPos.Account
WHERE (tblDatPositionsCalc_1.colDate =
(SELECT MAX(colDate) AS Expr1 FROM dbo.tblDatPositionsCalc))
ORDER BY
dbo.vwCurrPos.Account,
dbo.vwCurrPos.Id,
dbo.vwCurrPos.colEquityCode,
dbo.vwCurrPos.colRegion
Any idea what might cause the problem?
(Option 1) DrCopyPaste is right so your from clause would look like:
...
FROM dbo.vwCurrPos
LEFT OUTER JOIN dbo.tblDatPositionsCalc AS tblDatPositionsCalc_1
ON tblDatPositionsCalc_1.colId = dbo.vwCurrPos.Id
AND tblDatPositionsCalc_1.colAccount = dbo.vwCurrPos.Account
and (tblDatPositionsCalc_1.colDate =
(SELECT MAX(colDate) AS Expr1 FROM dbo.tblDatPositionsCalc))
...
reason: the where clause restriction of left joined to column = some expression with fail to return for "null = something" so the row will be removed.
(Option 2) As oppose to pushing code in to additional views where it is harder to maintain you can nest sql select statements;
select
X.x1,X.x2,
Y.*
from X
left join
(select Z.z1 as y1, Z.z2 as y2, Z.z3 as y3
from Z
where Z.z1 = (select max(Z.z1) from Z)
) as Y
on x.x1 = Y.y1 and X.x2 = Y.y2
The advantage here is you check each nested sub query a move out quickly. Although if you still building up more logic check out common table expressions (CTE's) http://msdn.microsoft.com/en-us/library/ms175972.aspx
I'm receiving a System.Data.SqlClient.SqlException: The server failed to resume the transaction. Desc:6c00000001 when executing a Linq-To-SQL query.
Here is my repository call:
using (var ctx = new EntitiesDataContext())
{
ctx.ObjectTrackingEnabled = false;
ctx.DeferredLoadingEnabled = false;
var loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Company2QualifierLicense>(n => n.QualifierLicense);
loadOptions.LoadWith<Company2QualifierLicense>(n => n.Company);
loadOptions.LoadWith<QualifierLicense>(n => n.QualifierLicenseHoldStatus);
loadOptions.LoadWith<QualifierLicense>(n => n.LicenseTrade);
loadOptions.LoadWith<Company>(n => n.CompanyHoldStatus);
ctx.LoadOptions = loadOptions;
return ctx.Company2QualifierLicenses.Where(p => p.QualifierLicense.QualifierLicenseNumber == qualifierLicense).ToList();
}
Here is the SQL generated:
-- Region Parameters
DECLARE #p0 VarChar(1000) = '11223344'
-- EndRegion
SELECT [t0].[CompanyID], [t0].[QualifierLicenseID], [t0].[InitiatedDate], [t0].[IsActive], [t0].[RowVersion], [t0].[LastUpdated], [t1].[QualifierLicenseID] AS [QualifierLicenseID2], [t1].[QualifierLicenseNumber], [t1].[LicenseTradeID], [t1].[LicenseExpirationDate], [t1].[FirstName], [t1].[LastName], [t1].[MailingAddress1], [t1].[MailingAddress2], [t1].[City], [t1].[StateAbbr], [t1].[ZIP], [t1].[Email], [t1].[Phone], [t1].[RowVersion] AS [RowVersion2], [t1].[LastUpdated] AS [LastUpdated2], [t3].[test], [t3].[LicenseTradeID] AS [LicenseTradeID2], [t3].[LicenseCode], [t3].[LicenseDescription], [t5].[QualifierLicenseHoldStatusID], [t5].[HoldReasonID], [t5].[QualifierLicenseID] AS [QualifierLicenseID3], [t5].[RowVersion] AS [RowVersion3], [t5].[LastUpdated] AS [LastUpdated3], (
SELECT COUNT(*)
FROM [frontdesk].[QualifierLicenseHoldStatus] AS [t6]
WHERE [t6].[QualifierLicenseID] = [t1].[QualifierLicenseID]
) AS [value], [t4].[CompanyID] AS [CompanyID2], [t4].[EIN], [t4].[CompanyName], [t4].[MailingAddress1] AS [MailingAddress12], [t4].[MailingAddress2] AS [MailingAddress22], [t4].[City] AS [City2], [t4].[StateAbbr] AS [StateAbbr2], [t4].[ZIP] AS [ZIP2], [t4].[Email] AS [Email2], [t4].[Phone] AS [Phone2], [t4].[RowVersion] AS [RowVersion4], [t4].[LastUpdated] AS [LastUpdated4]
FROM [frontdesk].[Company2QualifierLicense] AS [t0]
INNER JOIN ([frontdesk].[QualifierLicense] AS [t1]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t2].[LicenseTradeID], [t2].[LicenseCode], [t2].[LicenseDescription]
FROM [frontdesk].[LicenseTrade] AS [t2]
) AS [t3] ON [t3].[LicenseTradeID] = [t1].[LicenseTradeID]) ON [t1].[QualifierLicenseID] = [t0].[QualifierLicenseID]
INNER JOIN [frontdesk].[Company] AS [t4] ON [t4].[CompanyID] = [t0].[CompanyID]
LEFT OUTER JOIN [frontdesk].[QualifierLicenseHoldStatus] AS [t5] ON [t5].[QualifierLicenseID] = [t1].[QualifierLicenseID]
WHERE [t1].[QualifierLicenseNumber] = #p0
ORDER BY [t0].[CompanyID], [t0].[QualifierLicenseID], [t1].[QualifierLicenseID], [t3].[LicenseTradeID], [t5].[QualifierLicenseHoldStatusID]
GO
-- Region Parameters
DECLARE #x1 Int = 241
-- EndRegion
SELECT [t0].[CompanyHoldStatusID], [t0].[CompanyID], [t0].[HoldReasonID], [t0].[RowVersion], [t0].[LastUpdated]
FROM [frontdesk].[CompanyHoldStatus] AS [t0]
WHERE [t0].[CompanyID] = #x1
As you can see I'm creating and disposing of the DataContext immediately after the database query, so no further calls can be made from the calling method.
I see that there are two queries issued to the database and my guess is that when issuing the second query to the database the transaction has been committed, but Linq-To-SQL should be smarter than that.
I'm using .NET 4.0 and SQL Server 2008 R2 (SP1) - 10.50.2789.0
Any ideas?
UPDATE Dec/21/2011
Here is another piece of the exception:
The transaction active in this session has been committed or aborted by another session
UPDATE Dec/30/2011
A coworker found that this issue has been reported to Microsoft and it has been confirmed as a bug but it won't be fixed, and their recommendation is to move to Entity Framework.
A coworker found that this issue has been reported to Microsoft and it has been confirmed as a bug but it won't be fixed, and their recommendation is to move to Entity Framework.
A bit too long for comments.
You need to realize that eager loading in linq2sql does not work on multiple levels in a tree. So load b with a and c with b does not load a-b-c in one go.
http://www.lowendahl.net/showShout.aspx?id=190
This explains your additional second query.
Now why you get the exception I do not know.