I am having problems figuring out why a query is taking drastically longer to run based on me swapping out a parameter against a real value.
DECLARE #quarter int
DECLARE #year int
DECLARE #countOfUnitsBought int
set #year = 2009
set #quarter = 1
set #countOfUnitsBought = 4;
with res
as
(
select
o.account_id
--,orderyear
--,orderquarter
from
fmtables.[dbo].[orders] o
--cross apply(values(year(o.[ship_date]))) as a1(orderyear)
--cross apply(values(DatePart(quarter,(o.[ship_date])))) as a2(orderquarter)
where
ship_date = (select min(ship_date) from fmtables.[dbo].[orders] mo where [account_id] = o.account_id) and
total_value > 0 AND
order_status NOT LIKE 'return%' AND
order_status NOT LIKE 'cancel%' AND
order_status NOT LIKE 'freeze%' and
CAST(DatePart(quarter,(o.[ship_date])) as int) = #quarter and
year(o.[ship_date]) = #year and
(select sum(quantity) from fmtables..[orders] ox inner join fmtables..[orderlines] olx on ox.order_id = olx.order_id
where olx.order_id = o.order_id and [product_code] in(select [product_code] from fmtables..[products] where [category_code] in('1','2','3','4'))) >= #countOfUnitsBought
)
select * from res;
This query takes 43 seconds to run.
Now if I simply replace the #quarter and change to a literal
CAST(DatePart(quarter,(o.[ship_date])) as int) = 1 and
it now takes 1 second.
Can anyone please give me a clue as to why and if I need to change some casting to help.
Thanks
Scott
EDIT:
So I manage to get it whizzing through with the help of everyone's comments.
I used a mix of passing the parameters from the inputs and then through to a 'local' variable inside the procedure.
alter procedure [dbo].[Lifetime_HeadsetUnits]
#inquarter int , #inyear int, #incountOfUnitsBought int
as
DECLARE #quarter int
DECLARE #year int
declare #countOfUnitsBought int
select #quarter = #inquarter
select #year = #inyear
select #countOfUnitsBought = #incountOfUnitsBought
and also the
OPTION (OPTIMIZE FOR(#quarter = 1))
as part of the final output query.
Try this instead. I rewrote the datepart so indexes can be, used and the database is not making the long calculation on all rows. In other words I made your datecalculation sargable:
DECLARE #quarter int
DECLARE #year int
DECLARE #countOfUnitsBought int
set #year = 2009
set #quarter = 1
declare #from datetime = dateadd(quarter, #quarter - 1, cast(#year as char(4)))
set #countOfUnitsBought = 4;
with res
as
(
select
o.account_id
from
fmtables.[dbo].[orders] o
where
ship_date =
(select min(ship_date)
from fmtables.[dbo].[orders] mo
where [account_id] = o.account_id) and
total_value > 0 AND
order_status NOT LIKE 'return%' AND
order_status NOT LIKE 'cancel%' AND
order_status NOT LIKE 'freeze%' and
o.[ship_date] >= #quarter and
o.[ship_date] < DATEADD(QUARTER, 1, #from) and
(select sum(quantity) from fmtables..[orders] ox
inner join fmtables..[orderlines] olx on ox.order_id = olx.order_id
where [product_code] in(select [product_code] from fmtables..[products]
where [category_code] in('1','2','3','4'))) >= #countOfUnitsBought
)
select * from res;
Are you running an sql-server 2008 ? There is a bug that could also explain your performance issues.
Related
I have strange issue and I am getting more confused about this. I am using UWP on the .NET framework and using SQL Server as database. The problem is my application working too much slow and when I check my stored procedure execution time then I am notice that may be a problem is from the database stored procedure side.
My stored procedure sometimes takes 4-5 seconds to execute and sometimes takes more like 15-16 seconds and sometimes it takes more than 1 minute.
My questions are:
Why is it taking a lot more time sometimes, but not every time?
How can I solve this issue and boost my application execution time?
This is the stored procedure:
ALTER PROCEDURE [dbo].[SPNAME]
#HouseID INT,
#FromDate DATETIME,
#ToDate DATETIME,
#PageNumber INT,
#PageSize INT,
#RollID INT
AS
BEGIN
DECLARE #RoomID INT = 0
DECLARE #UnitID INT = 0
DECLARE #HouseCode INT = 0
DECLARE #StartRow INT
DECLARE #EndRow INT
SET #StartRow = #PageNumber
SET #StartRow = ((#StartRow-1) * #PageSize) + 1
SET #EndRow = (#StartRow + #PageSize) - 1;
IF OBJECT_ID('tempdb.dbo.#TableName') IS NOT NULL
DROP TABLE dbo.#TableName
SELECT
#HouseCode = [HouseCode],
#UnitID = UnitId
FROM
[dbo].[tblHouse]
WHERE
[HouseId] = #HouseID
SELECT #RoomID = RoomCode
FROM [dbo].[tblUnit] u
LEFT JOIN tblRoom h ON u.RoomID = h.Room
WHERE UnitID = #UnitID
SELECT MAX(RoNum) RoNum
INTO dbo.#tableName
FROM [dbo].[TAbleNAme]
WHERE FanId = #HouseCode
AND InActive = 0
AND ((InactivatedOn IS NULL AND StopDate IS NULL)
OR (ISNULL(InactivatedOn, StopDate) BETWEEN #FromDate AND #ToDate)
OR (ISNULL(InactivatedOn,StopDate) >= #ToDate))
AND (FirstFillDate <= #ToDate)
GROUP BY
OrigRoNum
SELECT
K.Topic, K.Comment, K.RoNum
INTO
#TmptblRoCom
FROM
[dbo].[TableNAme] K
LEFT JOIN
#TableName T ON K.RoNum = T.RoNum
WHERE
K.Topic = 'Nar Auto'
AND ISNUMERIC(SUBSTRING(K.Comment, 0, 3)) = 1
SELECT ButtonTypeID, ISNULL(SortOrder, 17) AS SortOrder
INTO dbo.#TableName
FROM [dbo].[TAbleName]
WHERE NHID = #RoomID AND NHSortID = 29
SELECT
DIN,
'LU: ' + LTRIM(RTRIM(ReasonCode)) +
'Exp:' + ISNULL(FORMAT(ExpiryDate, 'dd/MM/yyyy'), 'Indefinite') AS HLCode
INTO
dbo.#TableName
FROM
[dbo].[TableNAme]
WHERE
PatID = #HouseCode
AND (ExpiryDate IS NULL OR ExpiryDate > GETDATE())
SELECT
X.DgID AS DumbID,
X.ID AS RID,
CASE
WHEN DR.BandName IS NULL
THEN '#' + dm.Description
ELSE CONCAT(BandName, ' ', strength)
END AS DugName,
StrengthType, FormType,
CASE
WHEN GericName IS NULL
THEN
CASE
WHEN BandName IS NULL
THEN '#' + dm.Description
ELSE CONCAT(DR.BandName, ' ', DR.strength)
END
ELSE CONCAT(DR.GericName, ' ', DR.strengthTypr)
END AS GericName,
DR.[Description],
dbo.GetDirectionWithFullForm (X.IG,' ') AS Direction,
CAST(X.RoNum AS BIGINT) AS RoNum,
FORMAT(X.FirstFillDate,'dd/MM/yyyy') AS FirstFillDate,
FORMAT(X.LastFillDate,'dd/MM/yyyy') AS DugOrderDate,
ISNULL(TP.[ID],0) AS RollID,
TP.[Cont] AS Cont,
TP.[DisContinue] AS Disc,
TP.[Hold] AS Hold,
CAST(m.OrderType AS INT) AS OrderType,
pl.HLCode,
rc.Comment,
TP.[Comments]
FROM
dbo.#TAbleNAme rn
INNER JOIN
[dbo].[RollRx] X ON rn.RoNum = X.RoNum
INNER JOIN
[dbo].[RollDg] DR ON X.[DgID] = DR.ID
LEFT JOIN
[dbo].[RollDgMix] DM ON X.MixID = DM.ID
LEFT JOIN
[dbo].[RollPreviousNumber] TP ON X.DrgID = TP.[RollMedicationID]
AND X.[ID] = TP.[RoID]
AND TP.[HouseID] = #HouseID
AND TP.[TableName] = #RollID
LEFT JOIN
dbo.#TableNAme m ON m.TypeID = X.TypeID
LEFT JOIN
dbo.#TableName pl ON pl.DNNUM = X.DNNUM
LEFT JOIN
dbo.#TableName rc ON rc.RoNum = X.RoNum
END
Execution Plan
Yes sounds like parameter sniffing or lack of memory issue (this has made it block for me at times when I am running to much on my box), look at the execution plan.
Run the stored proc with your parameters and see if there is a difference here, by right clicking on the execution plan select, below shows an example.
I have a stored procedure that currently returns calculates statistics for employee to show on dashboard to track employee sale performance for individual employee.
Now, I am modifying that stored procedure to return the statistics to see the sales performance per department.
#EmployeeId int
#DepartmentId int,
SET #NewLeadForSlaes = (SELECT SUM(SaleStats)
FROM SaleSummary AS SS (nolock)
INNER JOIN CustomerSale AS CS ON SS.SaleId = CS.SaleId
WHERE CS.CityId = #CityId
AND CS.EmployeeId = #EmployeeId
AND SS.Type = 'Lead'
AND SS.Name = 'Sale'
AND (DATEFROMPARTS(SS.SaleYear, SS.SaleMonth, 1) >= #FromDate
AND DATEFROMPARTS(SS.SaleYear, SS.SaleMonth, 1) < #ToDate));
So when it will for EmployeeId, DepartmentId will be null and vice versa.
This is the condition for employee:
CS.EmployeeId = #EmployeeId
This is the condition for department:
CS.DepartmentId = #DepartmentId
How do I inject the condition dynamically but still keeps 1 query?
Give this a Try, Put an ISNULL as I have done below. Since You have already mentioned in your question that the #EmployeeId will be NULL for Department and Vice versa, a Simple ISNULL or a COALESCE should do the job for you
DECLARE
#EmployeeId int,
#DepartmentId int
SET #NewLeadForSlaes = (
SELECT
SUM(SaleStats)
FROM SaleSummary AS SS (nolock)
INNER JOIN CustomerSale AS CS
ON SS.SaleId = CS.SaleId
WHERE CS.CityId = #CityId
AND CS.EmployeeId = #EmployeeId
AND SS.Type = 'Lead'
AND SS.Name = 'Sale'
AND DATEFROMPARTS(SS.SaleYear, SS.SaleMonth, 1) >= #FromDate
AND DATEFROMPARTS(SS.SaleYear, SS.SaleMonth, 1) < #ToDate
AND CS.EmployeeId = ISNULL(#EmployeeId,CS.EmployeeId) -- Pass #EmployeeId as NULL for DepartmentId
AND CS.DepartmentId = ISNULL(#DepartmentId,CS.DepartmentId) -- Pass #DepartmentId as NULL for Employee
);
This is some what of a stab in the dark, if I am honest, but what I think you want is an OR which checks that value matches the value of the column while the other parameter is NULL. I also make some changes to the WHERE, such as making it SARGable (though really you should be adding a date column). I remove the NOLOCK, as I doubt you need it too.
DECLARE #EmployeeId int, --oddly the comma was missing here, but
#DepartmentId int;--, --there was a trailing comma here.
SELECT #NewLeadForSlaes = SUM(SaleStats) --Should this not be #NewLeadForSales? You're also missing the DECLARE
FROM dbo.SaleSummary AS SS --(NOLOCK) --Is there a good reason you're using the NOLOCk hint?
INNER JOIN CustomerSale AS CS ON SS.SaleId = CS.SaleId
WHERE CS.CityId = #CityId
AND ((CS.EmployeeId = #EmployeeId AND #DepartmentId IS NULL)
OR (CS.DepartmentId = #DepartmentId AND #EmployeeId IS NULL))
AND SS.Type ='Lead'
AND SS.Name ='Sale'
--This is SARGable but it's messy. Add a date (and time?) column to your table
AND ((SS.SaleYear = DATEPART(YEAR, #FromDate) AND SS.SaleMonth >= DATEPART(MONTH, #FromDate))
OR (SS.SaleYear > DATEPART(YEAR, #FromDate) AND SS.SaleYear < DATEPART(YEAR, #ToDate))
OR (SS.SaleYear = DATEPART(YEAR, #ToDate) AND SS.SaleMonth <= DATEPART(MONTH, #ToDate)))
OPTION (RECOMPILE);
Here is my SQL Query. It's insert almost 6500+ row from temp table. But its takes 15+ mins! . How can i improve this ? Thanks
ALTER proc [dbo].[Process_bill]
#userid varchar(10),
#remark nvarchar(500),
#tdate date ,
#pdate date
as
BEGIN
IF OBJECT_ID('tempdb.dbo..#temptbl_bill', 'U') IS NOT NULL
DROP TABLE #temptbl_bill;
CREATE TABLE #temptbl_bill (
RowID int IDENTITY(1, 1),
------------
)
// instert into temp table
DECLARE #NumberRecords int, #RowCounter int
DECLARE #batch INT
SET #batch = 300
SET #NumberRecords = (SELECT COUNT(*) FROM #temptbl_bill)
SET #RowCounter = 1
SET NOCOUNT ON
BEGIN TRANSACTION
WHILE #RowCounter <= #NumberRecords
BEGIN
declare #clid int
declare #hlid int
declare #holdinNo nvarchar(150)
declare #clientid nvarchar(100)
declare #clientName nvarchar(50)
declare #floor int
declare #radius nvarchar(50)
declare #bill money
declare #others money
declare #frate int
declare #due money
DECLARE #fine money
DECLARE #rebate money
IF #RowCounter > 0 AND ((#RowCounter % #batch = 0) OR (#RowCounter = #NumberRecords))
BEGIN
COMMIT TRANSACTION
PRINT CONCAT('Transaction #', CEILING(#RowCounter/ CAST(#batch AS FLOAT)), ' committed (', #RowCounter,' rows)');
BEGIN TRANSACTION
END;
// multiple select
// insert to destination table
Print 'RowCount -' +cast(#RowCounter as varchar(20)) + 'batch -' + cast(#batch as varchar(20))
SET #RowCounter = #RowCounter + 1;
END
COMMIT TRANSACTION
PRINT CONCAT('Transaction #', CEILING(#RowCounter/ CAST(#batch AS FLOAT)), ' committed (',
#RowCounter,' rows)');
SET NOCOUNT OFF
DROP TABLE #temptbl_bill
END
GO
As has been said in comments, the loop is completely unnecessary. The way to improve the performance of any loop is to remove it completely. Loops are a last resort in SQL.
As far as I can tell your insert can be written with a single statement:
INSERT tbl_bill(clid, hlid, holdingNo,ClientID, ClientName, billno, date_month, unit, others, fine, due, bill, rebate, remark, payment_date, inserted_by, inserted_date)
SELECT clid = c.id,
hlid = h.id,
h.holdinNo ,
c.cliendID,
clientName = CAST(c.clientName AS NVARCHAR(50)),
BillNo = CONCAT(h.holdinNo, MONTH(#tdate), YEAR(#tdate)),
date_month = #tDate,
unit = 0,
others = CASE WHEN h.hfloor = 0 THEN rs.frate * (h.hfloor - 1) ELSE 0 END,
fine = bs.FineRate * b.Due / 100,
due = b.Due,
bill = #bill, -- This is declared but never assigned
rebate = bs.rebate,
remark = #remark,
payment_date = #pdate,
inserted_by = #userid,
inserted_date = GETDATE()
FROM ( SELECT id, clientdID, ClientName
FROM tbl_client
WHERE status = 1
) AS c
INNER JOIN
( SELECT id, holdinNo, [floor], connect_radius
FROM tx_holding
WHERE status = 1
AND connect_radius <> '0'
AND type = 'Residential'
) AS h
ON c.id = h.clid
LEFT JOIN tbl_radius_setting AS rs
ON rs.radius= CONVERT(real,h.connect_radius)
AND rs.status = 1
AND rs.type = 'Non-Govt.'
LEFT JOIN tbl_bill_setting AS bs
ON bs.Status = 1
LEFT JOIN
( SELECT hlid,
SUM(netbill) AS Due
FROM tbl_bill AS b
WHERE date_month < #tdate
AND (b.ispay = 0 OR b.ispay IS NULL)
GROUP BY hlid
) AS b
ON b.hlid = h.id
WHERE NOT EXISTS
( SELECT 1
FROM tbl_bill AS tb
WHERE EOMONTH(#tdate) = EOMONTH(date_month)
AND tb.holdingNo = h.holdinNo
AND (tb.update_by IS NOT NULL OR tb.ispay=1)
);
Please take this with a pinch of salt, it was quite hard work trying to piece together the logic, so it may need some minor tweaks and corrections
As well as adapting this to work as a single statement, I have made a number of modifications to your existing code:
Swapped NOT IN for NOT EXISTS to avoid any issues with null records. If holdingNo is nullable, they are equivalent, if holdingNo is nullable, NOT EXISTS is safer - Not Exists Vs Not IN
The join syntax you are using was replaced 27 years ago, so I switched from ANSI-89 join syntax to ANSI-92. - Bad habits to kick : using old-style JOINs
Changed predicates of YEAR(date_month) = YEAR(#tDate) AND MONTH(date_month) = MONTH(#tDate) to become EOMONTH(#tdate) = EOMONTH(date_month). These are syntactically the same, but EOMONTH is Sargable, whereas MONTH and YEAR are not.
Then a few further links/suggestions that are directly related to changes I have made
Although I removed the while lopp, don't fall into the trap of thinking this is better than a cursor. A properly declared cursor will out perform a while loop like yours - Bad Habits to Kick : Thinking a WHILE loop isn't a CURSOR
The general consensus is that prefixing object names is not a good idea. It should either be obvious from the context if an object is a table/view or function/procedure, or it should be irrelevant - i.e. There is no need to distinguish between a table or a view, and in fact, we may wish to change from one to the other, so having the prefix makes things worse, not better.
The average ratio of time spent reading code to time spent writing code is around 10:1 - It is therefore worth the effort to format your code when you are writing it so that it is easy to read. This is hugely subjective with SQL, and I would not recommend any particular conventions, but I cannot believe for a second you find your original code free flowing and easy to read. It took me about 10 minutes just unravel the first insert statement.
EDIT
The above is not correct, EOMONTH() is not sargable, so does not perform any better than YEAR(x) = YEAR(y) AND MONTH(x) = MONTH(y), although it is still a bit simpler. If you want a truly sargable predicate you will need to create a start and end date using #tdate, so you can use:
DATEADD(MONTH, DATEDIFF(MONTH, '19000101', #tdate), '19000101')
to get the first day of the month for #tdate, then almost the same forumla, but add months to 1st February 1900 rather than 1st January to get the start of the next month:
DATEADD(MONTH, DATEDIFF(MONTH, '19000201', #tdate), '19000201')
So the following:
DECLARE #Tdate DATE = '2019-10-11';
SELECT DATEADD(MONTH, DATEDIFF(MONTH, '19000101', #tdate), '19000101'),
DATEADD(MONTH, DATEDIFF(MONTH, '19000201', #tdate), '19000201');
Will return 1st October and 1st November respectively. Putting this back in your original query would give:
WHERE NOT EXISTS
( SELECT 1
FROM tbl_bill AS tb
WHERE date_month >= DATEADD(MONTH, DATEDIFF(MONTH, '19000101', #tdate), '19000101'),
AND date_month < DATEADD(MONTH, DATEDIFF(MONTH, '19000201', #tdate), '19000201')
AND tb.holdingNo = h.holdinNo
AND (tb.update_by IS NOT NULL OR tb.ispay=1)
);
can some one help, with this query. I have 10 rows in my temp table
Declare #date date = '2014-11-01'
Declare #iDate int = '20141101'
Create table #test33(Paname varchar(100))
insert into #test33
Go
Now i have 10 rows in temp table. I want to insert those temp values in my cte dynamically
Declare #StartDate date = '2014-11-01'
Declare #EndDate date = '2014-11-30'
Declare #Paname nvarchar(100) = 'MPU' --- i have multiple panames how can i insert dyamically in cte or any other solution?
;with pla as
( SELECT*
FROM [dbo].[Pla] pl
JOIN dbo.testplan cl
ON pl.ClientId = cl.ClientId
where pl.name = #Paname
and pl.StartDate >= #StartDate and pl.EndDate <= #EndDate
)
select * from pla
You can loop throw multiple parameters using WHILE or using CURSOR. Inside it you can used dynamic sql:
declare #DSQL varchar(MAX)
SET #DSQL = ';with pla as
( SELECT*
FROM [dbo].[Pla] pl
JOIN dbo.testplan cl
ON pl.ClientId = cl.ClientId
where pl.name = '+#Paname+'
and pl.StartDate >= '+#StartDate+' and pl.EndDate <= '+#EndDate+'
)
select * from pla'
EXEC(#DSQL)
I'm trying to compare the sum of 2 different columns and I'm getting an error saying that I must declare #Base. Then I have tried to do something like #Base AS B, the error will disappear. But I'm not retrieving any data.
Can anyone help me with if I have made a typo or my INNER JOIN is wrong?
Declare #Base table(PickupDate smalldatetime, DeliveryDate smalldatetime, PickupAdrID int, PickupCustID varchar(10), DeliveryType char, DeliveryAdrID int, DeliveryCustID varchar(10), DeliveryAlias varchar (30), Volumen float, Weight float) Insert #Base(PickupDate,DeliveryDate, PickupAdrID, PickupCustID, DeliveryType, DeliveryAdrID, DeliveryCustID, DeliveryAlias, Volumen,Weight)
SELECT PickupDate,DeliveryDate, PickupAdrID, PickupCustID, DeliveryType, DeliveryAdrID, DeliveryCustID, DeliveryAlias, Volumen, Weight
FROM Sending
INNER JOIN Address_ViewI ON Sending.PickupAdrID = Address_ViewI.AdrID
INNER JOIN Address_ViewI AS Address_View_DE ON Sending.DeliveryAdrID = Address_View_DE.AdrID
WHERE (Address_ViewI.CountryUK = #puC AND Address_View_DE.CountryUK = #deC) AND (Sending.PickupDate >= #start) AND (Sending.PickupDate < #end) AND ((PickUpCustID Like 'TMHSE' OR DeliveryCustID like 'TMHSE' ) )
OR (Address_ViewI.CountryUK = #puC AND Address_View_DE.CountryUK = #deC) AND (Sending.PickupDate >= #start) AND (Sending.PickupDate < #end) AND ((PickUpCustID Like 'SomeName' OR DeliveryCustID like 'SomeName' ) )
SELECT totals.DeliveryAdrID, totals.PickupDate,
(CASE WHEN weightTOTAL <= volumenTOTAL THEN volumenTOTAL
WHEN weightTOTAL >= volumenTOTAL THEN weightTOTAL ELSE weightTOTAL END) AS InvoiceWeight
FROM #Base INNER JOIN
(SELECT DeliveryAdrID, CONVERT(CHAR(10),PickupDate,110) AS PickupDate,
CEILING(SUM(CASE Weight When 0 Then #zeroKiloVal ELSE Weight END)) AS WeightTOTAL,
CEILING(SUM(CASE Volumen WHEN 0 THEN (#zeroVoluVal * #zeroVoluFac) ELSE Volumen END)) AS volumenTOTAL,
COUNT(DeliveryAdrID)AS Packages
FROM #Base GROUP BY CONVERT(CHAR(10),PickupDate,110), DeliveryAdrID ) AS totals
ON #Base.DeliveryAdrID = totals.DeliveryAdrID AND CONVERT(CHAR(10),#Base.PickupDate,110) = totals.PickupDate
The full code is listed here http://pastie.org/8238866
And the error I'm getting
It worked for me when I placed an alias on the reference to #Base
Declare #zeroKiloVal float = 10
Declare #zeroVoluVal float = 10
Declare #zeroVoluFac float = 200
Declare #puC varchar = 'Sweden'
Declare #deC varchar = 'Sweden'
Declare #start smalldatetime = '2013-04-21'
Declare #end smalldatetime = '2013-05-01'
DECLARE #Base TABLE (SendingID INT, Barcode VARCHAR(50), PickupType CHAR, PickupDate SMALLDATETIME, DeliveryDate SMALLDATETIME, PickupAdrID INT, PickupCustID VARCHAR(10), DeliveryType CHAR, DeliveryAdrID INT, DeliveryCustID VARCHAR(10), DeliveryAlias VARCHAR (30), Volumen FLOAT, [Weight] FLOAT)
INSERT INTO #Base(SendingID, Barcode, PickupType, PickupDate,DeliveryDate, PickupAdrID, PickupCustID, DeliveryType, DeliveryAdrID, DeliveryCustID, DeliveryAlias, Volumen,[Weight])
SELECT SendingID = 1, Barcode= 1, PickupType= 1, PickupDate= 1,DeliveryDate= 1, PickupAdrID= 1, PickupCustID= 1, DeliveryType= 1, DeliveryAdrID= 1, DeliveryCustID= 1, DeliveryAlias= 1, Volumen= 1, [Weight] = 1
-- Replacing below code with stubbed data for testing.
-- SELECT SendingID, Barcode, PickupType, PickupDate,DeliveryDate, PickupAdrID, PickupCustID, DeliveryType, DeliveryAdrID, DeliveryCustID, DeliveryAlias, Volumen, Weight
-- FROM Sending
-- INNER JOIN Address_ViewI ON Sending.PickupAdrID = Address_ViewI.AdrID
-- INNER JOIN Address_ViewI AS Address_View_DE ON Sending.DeliveryAdrID = Address_View_DE.AdrID
-- WHERE (Address_ViewI.CountryUK = #puC AND Address_View_DE.CountryUK = #deC) AND (Sending.PickupDate >= #start) AND (Sending.PickupDate < #end) AND ((PickUpCustID Like 'TMHSE' OR DeliveryCustID like 'TMHSE' ) )
-- OR (Address_ViewI.CountryUK = #puC AND Address_View_DE.CountryUK = #deC) AND (Sending.PickupDate >= #start) AND (Sending.PickupDate < #end) AND ((PickUpCustID Like 'TMHSE' OR DeliveryCustID like 'TMHSE' ) )
SELECT totals.DeliveryAdrID
, totals.PickupDate
, InvoiceWeight =
(
CASE WHEN weightTOTAL <= volumenTOTAL THEN volumenTOTAL
WHEN weightTOTAL >= volumenTOTAL THEN weightTOTAL ELSE weightTOTAL END
)
FROM #Base AS B -- <<Added alias here>>
INNER JOIN
(
SELECT DeliveryAdrID
, PickupDate = CONVERT(CHAR(10),PickupDate,110)
, WeightTOTAL = CEILING(SUM(CASE [Weight] WHEN 0 THEN #zeroKiloVal ELSE [Weight] END))
, volumenTOTAL = CEILING(SUM(CASE Volumen WHEN 0 THEN (#zeroVoluVal * #zeroVoluFac) ELSE Volumen END))
, Packages = COUNT(DeliveryAdrID)
FROM #Base
GROUP BY CONVERT(CHAR(10),PickupDate,110), DeliveryAdrID
) AS totals ON B.DeliveryAdrID = totals.DeliveryAdrID
AND CONVERT(CHAR(10),B.PickupDate,110) = totals.PickupDate
Maybe you need to use some wildcards in the constants being compared with the Like operator, such as:
PickUpCustID Like '%TMHSE%' OR DeliveryCustID like '%TMHSE%'
Otherwise, I think you're just doing the same as
PickUpCustID = 'TMHSE' OR DeliveryCustID = 'TMHSE'
or
'TMHSE' in (PickUpCustID, DeliveryCustID)
I figured out the error it seems that my declared variables was missing something:
Declare #puC varchar = 'Sweden'
Declare #deC varchar = 'Sweden'
I changed it to
Declare #puC varchar (50) = 'Sweden'
Declare #deC varchar (50) = 'Sweden'
Thanks for your time guys