I have very typical situation where I'm doing wrong. I have query which have executed fast initially but later on it taking loads of time to execute ..
My query :
Declare
#fromdate varchar(20) = '01/01/2014',
#todate varchar(20)= '27/05/2015',
#SERVICE_ID CHAR(5) = '123'
DECLARE #FDATE DATETIME ,
#TDATE DATETIME
SET #FDATE = (CONVERT(DATETIME,#fromdate,103))
SET #TDATE = (CONVERT(DATETIME,#todate,103))
IF OBJECT_ID('tempdb..#RUID') IS NOT NULL
DROP TABLE #RUID
CREATE TABLE #RUID(
OFFICEID INT,
OFFICE_TITTLE INT,
MAIN_OFFICE_TITTLE VARCHAR(50),
RLB_NAME VARCHAR(20),
DIST_NAME INT,
district_description VARCHAR(30))
CREATE CLUSTERED INDEX IDX_C_RUID_ID ON #RUID(OFFICEID)
CREATE NONCLUSTERED INDEX IDX_RUID_Name ON #RUID(OFFICE_TITTLE,DIST_NAME)INCLUDE(district_description)
INSERT INTO #RUID
SELECT OFFICEID,
OFFICE_TITTLE,
MAIN_OFFICE_TITTLE,
RLB_NAME,
DIST_NAME,
D.district_description
FROM APSDC..DISTRICT D
INNER JOIN cdma..Unified_RUID_WARD_MSTR I WITH(NOLOCK)
ON D.CDMA_DistrictID = I.DIST_NAME
WHERE RLB_NAME in(3) AND I.STATEID ='01'
select C.MAIN_OFFICE_TITTLE AS 'OFFICE_TITTLE',C.officeid, C.DIST_NAME AS DistrictName, C.district_description,
ISNULL(count(I.ApplicationNumber),0) 'Total_Trans',
isnull(sum(case when Data_Available='Y' AND DataTampered = 'N' then 1 else 0 end),0) 'CategoryA'
from #RUID c with(nolock)
LEFT JOIN Unified_BirthDeathAppDetails I WITH(NOLOCK) ON
(C.OFFICE_TITTLE=I.RUID AND C.DIST_NAME=I.DistrictName)
AND I.Service_Type= '01' AND
(DATEADD(DD,0,DATEDIFF(DD,0,I.Created_Date))) BETWEEN #FDATE AND #TDATE
AND NOT EXISTS(select application_number from reversal_details WITH(NOLOCK) WHERE ApplicationNumber <> i.ApplicationNumber AND service_id='123' )
group by C.MAIN_OFFICE_TITTLE,C.officeid, C.DIST_NAME,C.district_description
order by C.district_description ,C.MAIN_OFFICE_TITTLE
I have tried with #temp table and table variable but it is not even showing any result set. But the same query executed in 2 secs now it is taking lot of time. I have tried UPDATE Statstics on this tables and I have checked with locking also. What I need to do I have followed every other peformance optimized techinique.
Try:
Declare
#FDate Date = '01/01/2014',
#TDate Date= '27/05/2015',
#SERVICE_ID CHAR(5) = '123'
;WITH RUID
AS
(
SELECT OFFICEID,
OFFICE_TITTLE,
MAIN_OFFICE_TITTLE,
RLB_NAME,
DIST_NAME,
D.district_description
FROM APSDC..DISTRICT D
INNER JOIN cdma..Unified_RUID_WARD_MSTR I
ON D.CDMA_DistrictID = I.DIST_NAME
WHERE RLB_NAME in(3) AND I.STATEID ='01'
),
AppDetails
AS
(
SELECT ApplicationNumber,
CASE WHEN Data_Available='Y' AND DataTampered = 'N'
THEN 1
ELSE 0
END CategoryA
FROM Unified_BirthDeathAppDetails I
WHERE I.CreateDate >= #FDate AND I.CreatedDate < #TDate AND
NOT EXISTS
( select application_number
FROM reversal_details
WHERE I.Service_Type= '01' AND
ApplicationNumber <> i.ApplicationNumber AND
service_id= #Service_iD
)
)
SELECT C.MAIN_OFFICE_TITTLE AS OFFICE_TITTLE
,C.officeid, C.DIST_NAME AS DistrictName
, C.district_description
,ISNULL(count(I.ApplicationNumber),0) Total_Trans
,isnull(sum(CategoryA),0) CategoryA
FROM RUID c
LEFT JOIN AppDetails I
ON C.OFFICE_TITTLE=I.RUID AND C.DIST_NAME=I.DistrictName
GROUP BY C.MAIN_OFFICE_TITTLE
,C.officeid
,C.DIST_NAME
,C.district_description
ORDER BU C.district_description
,C.MAIN_OFFICE_TITTLE
Make sure you have decent indexes on RLB_name, StateId, CDMA_DistrictId, Dist_Name, CreatedDate etc.
Related
I am trying to improve old while loop query. So far tried this but it is still slow. Not sure may be SUM perform slow.
Old query (10 mins+)
ALTER PROCEDURE [dbo].[process_tax]
#userid VARCHAR(10),
#remark NVARCHAR(500),
#tdate DATE,
#roadno NVARCHAR(10),
#inst INT
AS
BEGIN
IF OBJECT_ID('tempdb..#tempProcess_tax_1') IS NOT NULL
DROP TABLE #tempProcess_tax_1
CREATE TABLE #tempProcess_tax_1
(
RowID INT IDENTITY(1, 1),
clid_ INT,
hlid_ INT,
holdinNo_ NVARCHAR(500),
holding_ NVARCHAR(50),
clientid_ NVARCHAR(500),
clientName_ NVARCHAR(500)
)
INSERT INTO #tempProcess_tax_1 (clid_, hlid_, holdinNo_, holding_, clientid_, clientName_)
SELECT
cl.clid AS clid_, cl.id AS hlid_, holdinNo, holding,
ClientID AS clientid_, ClientName AS clientName_
FROM
tx_holding AS cl
WHERE
cl.status = 1 AND cl.roadno = #roadno
AND cl.id IN (SELECT hlid FROM tx_asset WHERE asset IS NOT NULL)
AND cl.clid IN (SELECT id FROM tbl_client WHERE client_type = 'Non-Govt.')
AND cl.id NOT IN (SELECT hlid FROM tx_bill_pay
WHERE YEAR(date_month) = YEAR(#tdate)
AND hlid IS NOT NULL
GROUP BY hlid)
DECLARE #NumberRecords_1 INT, #RowCounter_1 INT
SET #NumberRecords_1 = (SELECT COUNT(*) FROM #tempProcess_tax_1)
SET #RowCounter_1 = 1
WHILE #RowCounter_1 <= #NumberRecords_1
BEGIN
DECLARE #clid_ INT
DECLARE #hlid_ INT
DECLARE #holdinNo_ NVARCHAR(50)
DECLARE #holding_ NVARCHAR(50)
DECLARE #clientid_ NVARCHAR(100)
DECLARE #clientName_ NVARCHAR(250)
DECLARE #bill AS MONEY
DECLARE #sr AS MONEY;
SELECT
#clid_ = clid_,
#hlid_ = hlid_,
#holdinNo_ = holdinNo_, #holding_ = holding_,
#clientid_ = clientid_, #clientName_ = clientName_
FROM
#tempProcess_tax_1
WHERE
RowID = #RowCounter_1
SET #bill = (SELECT
CASE WHEN SUM(netvalue) IS NULL
THEN 0
ELSE SUM(netvalue)
END
FROM
tx_bill
WHERE
hlid = #hlid_
AND itemID NOT IN (8, 6)
AND YEAR(date_month) = YEAR(#tdate))
SET #sr = (SELECT
CASE WHEN SUM(asset * rate / 100) IS NULL
THEN 0
ELSE SUM(asset * rate / 100)
END
FROM
tx_bill
WHERE
hlid = #hlid_
AND itemID = 6
AND YEAR(date_month) = YEAR(#tdate))
INSERT INTO tx_bill_pay(clid, hlid, swercharge, pay_bill, pdate, bill_id, holdingNo, holding, ClientID, ClientName, billno, date_month, bill, install, inserted_by, inserted_date)
VALUES (#clid_, #hlid_, #sr, #bill / 4, DATEADD(day, -1, DATEADD(m, 3, #tdate)), CONCAT(#holdinNo_, YEAR(#tdate), '1'), #holdinNo_, #holding_, #clientid_, #clientName_, CONCAT(#holdinNo_, YEAR#tdate)), #tdate, #bill, 1, #userid, GETDATE())
INSERT INTO tx_bill_pay(clid, hlid, swercharge, pay_bill, pdate, bill_id, holdingNo, holding, ClientID, ClientName, billno, date_month, bill, install, inserted_by, inserted_date)
VALUES (#clid_, #hlid_, 0, 2 * (#bill / 4), DATEADD(day, -1, DATEADD(m, 6, #tdate)), CONCAT(#holdinNo_, YEAR(#tdate), '2'), #holdinNo_, #holding_, #clientid_, #clientName_, CONCAT(#holdinNo_, YEAR(#tdate)), #tdate, #bill, 2, #userid, GETDATE())
SET #RowCounter_1 = #RowCounter_1 + 1
END
DROP TABLE #tempProcess_tax_1
END
New query (1-2 mins)
ALTER PROCEDURE [dbo].[process_tax]
#userid varchar(10),
#remark nvarchar(500),
#tdate date ,
#roadno nvarchar(10),
#inst int
as
BEGIN
insert into tx_bill_pay(
clid,
hlid,
swercharge,
pay_bill,
pdate,
bill_id,
holdingNo,
holding,
ClientID,
ClientName,
billno,
date_month,
bill,
install ,
inserted_by,
inserted_date)
select
cl.clid,
cl.id,
swercharge=(select case when sum(asset*rate/100) is null then 0 else
sum(asset*rate/100) end from tx_bill where hlid=cl.id and
itemID =6 and year(date_month)=YEAR(#tdate)),
pay_bill=(select case when sum(netvalue) is null then 0 else
sum(netvalue) end from tx_bill where hlid=cl.id and itemID not
in(8,6) and year(date_month)=YEAR(#tdate))/4,
DATEADD(day,-1,
DATEADD(m,3,#tdate)),
CONCAT(cl.holdinNo, year(#tdate),'1'),
cl.holdinNo,
cl.holding,
cl.ClientID,
cl.clientName,
CONCAT(cl.holdinNo,
year(#tdate)),
#tdate,
bill=(select case when sum(netvalue) is null then 0 else sum(netvalue)
end from tx_bill where hlid=cl.id and itemID not in(8,6) and
year(date_month)=YEAR(#tdate))/4,
1,
#userid, getdate()
from
(select *
from tx_holding as cl
where cl.status=1 and cl.roadno=#roadno) AS cl
INNER JOIN (
select DISTINCT hlid from tx_asset where asset is not null
) AS A
ON Cl.id = A.hlid
INNER JOIN (
select DISTINCT id from tbl_client where client_type='Non-Govt.'
) AS C
ON cl.clid=C.id
WHERE NOT EXISTS
( SELECT 1
FROM tx_bill_pay as bp
WHERE year(date_month)=year(#tdate)
and bp.hlid=cl.id
)
insert into tx_bill_pay(clid,hlid
,swercharge,pay_bill,pdate,bill_id,holdingNo,holding,ClientID,
ClientName, billno, date_month, bill, install ,inserted_by,
inserted_date)
select
cl.clid,
cl.id,
0,
pay_bill=2*((select case when sum(netvalue) is null then 0 else sum(netvalue) end from tx_bill where hlid=cl.id and itemID not in(8,6) and year(date_month)=YEAR(#tdate))/4),
DATEADD(day,-1,
DATEADD(m,3,#tdate)),
CONCAT(cl.holdinNo, year(#tdate),'2'),
cl.holdinNo,
cl.holding,
cl.ClientID,
cl.clientName,
CONCAT(cl.holdinNo, year(#tdate)) ,
#tdate,
bill=(select case when sum(netvalue) is null then 0 else sum(netvalue)
end from tx_bill where hlid=cl.id and itemID not in(8,6) and year(date_month)=YEAR(#tdate))/4,
2,
#userid, getdate()
from
(select *
from tx_holding as cl
where cl.status=1 and cl.roadno=#roadno) AS cl
INNER JOIN (
select DISTINCT hlid from tx_asset where asset is not null
) AS A
ON Cl.id = A.hlid
INNER JOIN (
select DISTINCT id from tbl_client where client_type='Non-Govt.'
) AS C
ON cl.clid=C.id
WHERE cl.id not in
( SELECT hlid
FROM tx_bill_pay
WHERE year(date_month)=year(#tdate)
and hlid is not null group by hlid
)
Great Job removing the loop!
I will point out one possible performance problem, specifically year(date_month)=year(#tdate).
Because a column is wrapped in a function, it is non-SARGABLE. This means that date_month values cannot be evaluated directly and therefore, indexes and statistics for this column cannot be used.
To resolve this I suggest the following changes:
At the top of the SP define two more variables:
DECLARE #YearStart AS DATETIME, #NextYearStart DATETIME
SET #YearStart = DATEADD(yy, DATEDIFF(yy, 0, #tdate ), 0 )
SET #NextYearStart = DATEADD( yy, #YearStart, 1 )
Then replace all instances of year(date_month)=year(#tdate) with
#YearStart <= date_month AND date_month < #NextYearStart
This above expression looks for date_month values greater than or equal to midnight (notice that time component is accounted for) of the first day of the year and less than midnight of the next year.
Next, I would look at the query plan and see if SQL Server gives a "Missing Index" recommendation (it should appear just above the plan diagram, if it does suggest an index). Try adding the recommended missing indexes, then check to see if you get a performance improvement. If you don't get an improvement, remove the index - sometimes suggestions don't help.
Updated
Having 3 sub-queries (populating columns swercharge, pay_bill, bill) using tx_bill table with different WHERE conditions will cause at least 3 evaluations of this table per one main query execution.
It may, depending on the size of the table, be more efficient to calculate all 3 sub-queries once and save results to a temp table (or a table variable) as follows:
SELECT hlid,
ISNULL( SUM( CASE WHEN itemID NOT IN (8, 6) THEN netvalue END ), 0 ) AS Bill,
ISNULL( SUM( CASE WHEN itemID = 6 THEN asset * rate / 100 END ), 0 ) AS Sr
INTO #Bills
FROM tx_bill
WHERE #YearStart <= date_month AND date_month < #NextYearStart
AND NOT hlid IS NULL
GROUP BY hlid
In your main queries, join to this table as follows:
LEFT JOIN #SumBills AS SumBills ON SumBills.hlid = cl.hlid
and in SELECT change assignments as per below example:
pay_bill= ISNULL( SumBills.Bill, 0 ) / 4,
Note: I believe you have a bug in bill column, as the value is divided by 4, where it is not in the original cursor.
The last point:
As #GarethD has said in his answer to your previous question, properly formatting your code significantly reduces the time it takes to understand and change the code. I would go one step further and say that code format represents your attitude to and understanding of the problem at hand.
I added non clustered index then my query take 5 sec to run.That's almost solve my problem. #Alex Thanks for your hard work and time. I will check your tips.I Up vote your comment
I can get the total for each of the items from a derived table like so:
declare #laneNum int
declare #startDate date = '2019-02-07'
declare #class int = 1
declare #id int
if OBJECT_ID('tempdb..#tempLaneNumber') IS NOT NULL
drop table [#tempLaneNumber]
create table #tempLaneNumber
(
LANE_NUMBER INT NULL
)
INSERT INTO #tempLaneNumber (LANE_NUMBER)
SELECT DISTINCT EXIT_LANE
FROM [dbo].[TOLL]
ORDER BY EXIT_LANE DESC
select l.LANE_NUMBER, COUNT(*)
from [dbo].[TOLL] t
inner join #tempLaneNumber l on t.EXIT_LANE = l.LANE_NUMBER
where convert(date, TRXN_DTIME) = #startDate
GROUP BY l.LANE_NUMBER
But what I need now is to iterate through each of the derived values so I can use it in a statement where each result can be placed in a variable. This is what I get in my current code...
I need to put LANE_NUMBER 4 into x4 variable and LANE_NUMBER 6 into x6 variable and so forth. How do I get to it?
EDIT
declare #laneNum int
declare #startDate date = '2019-02-07'
declare #class int = 1
declare #id int
if OBJECT_ID('tempdb..#tempLaneNumber') IS NOT NULL
drop table [#tempLaneNumber]
create table #tempLaneNumber
(
LANE_NUMBER INT NULL
)
INSERT INTO #tempLaneNumber (LANE_NUMBER)
SELECT DISTINCT EXIT_LANE
FROM [dbo].[TOLL]
ORDER BY EXIT_LANE DESC
;WITH CTE AS
(
select l.LANE_NUMBER, COUNT(*) CT
from [dbo].[TOLL] t
inner join #tempLaneNumber l on t.EXIT_LANE = l.LANE_NUMBER
where convert(date, TRXN_DTIME) = #startDate
GROUP BY l.LANE_NUMBER
)
SELECT * FROM CTE where LANE_NUMBER = 4
This is about right but the problem is I would need to hardcode the value "4" or "6" or "7". This sample has 4 results so it's okay. but what if I have 10 or more?
If you want to use the result later on you can use temp table like following.
create table #Results
(
LANE_NUMBER INT NULL,
[Count_LN] INT
)
INSERT INTO #Results
select l.LANE_NUMBER, COUNT(*) CT
from [dbo].[TOLL] t
inner join #tempLaneNumber l on t.EXIT_LANE = l.LANE_NUMBER
where convert(date, TRXN_DTIME) = #startDate
GROUP BY l.LANE_NUMBER
If you want to use the output immediately in the next statement, you can go for CTE like following.
;WITH CTE AS
(
select l.LANE_NUMBER, COUNT(*) CT
from [dbo].[TOLL] t
inner join #tempLaneNumber l on t.EXIT_LANE = l.LANE_NUMBER
where convert(date, TRXN_DTIME) = #startDate
GROUP BY l.LANE_NUMBER
)
SELECT * FROM CTE --USER YOUR CTE HERE
EDIT:
I am not able to understand your requirement fully, by any reason if you want to iterate the table and store every row's column value into a variable, you can try like following.
create table #Results
(
LANE_NUMBER INT NULL,
[Count_LN] INT
)
INSERT INTO #Results
select l.LANE_NUMBER, COUNT(*) CT
from [dbo].[TOLL] t
inner join #tempLaneNumber l on t.EXIT_LANE = l.LANE_NUMBER
where convert(date, TRXN_DTIME) = #startDate
GROUP BY l.LANE_NUMBER
declare #ln int
declare #ct int
While (Select Count(*) From #Results) > 0
Begin
select top 1 #ln = LANE_NUMBER, #ct = [Count_LN] from #Results
-- Use the variable #ln and #ct. For example, if you want to call a sp
-- exec call_someothersp #ln,#ct
Delete From #Results Where LANE_NUMBER = #ln and [Count_LN]=#ct
End
This question already has an answer here:
Drop temp table within IF ELSE statement
(1 answer)
Closed 7 years ago.
I have the following stored procedure, But seems like the #Temp table is creating troubles in it. I get following error
There is already an object named '#Temp' in the database.
I guess somethings wrong with my IF ELSE
Here is the stored procedure:
create procedure spGetHOSalesReport
#DateFrom datetime,#DateTo datetime,#EmbossLine varchar(20),#CountryID int,#status char(2)
AS
Set #DateTo = #DateTo +1
if(#status = 'E1')
begin
Select PT.[ID] 'TransactionID', PT.BatchNumber, PT.SequenceNumber, PT.TransactionDate,
PT.TerminalID, PT.TotalAmount, PT.TransactionTypeID, TT.TransactionType,PT.PAN 'EmbossLine',PT.PreBalanceAmount, PT.PostBalanceAmount, RefTxnID, SettlementDate,PaidCash, CreditAmount, DiscountAmount,
RefPAN, PT.Remarks, ' ' + CashierCard as 'SupervisorCard',St.StoreID
into #Temp
from TempPOS_Transactions PT inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
inner join Staff St on St.CardNumber=PT.CashierCard
where
PT.[ID] not in (Select distinct isnull(TransactionID,0) from Testcards)
and (PT.TransactionDate >= #DateFrom) and (PT.TransactionDate < #DateTo)
and (PT.TransactionTypeID = 6) and (PT.BatchNumber = 0) and (Pt.SequenceNumber =-1)
select T.*, ' '+ C.EmbossLine+' ' as 'EmbossLine', C.EmbossLine as 'EmbossLine1',
isnull(C.FirstName,'') +' '+ isnull(C.LastName,'') 'EmbossName',C.FirstName,C.LastName,City.CityName,Country.CountryName,Country.CurrencyName, PM.MerchantID, PM.MerchantName1, C.AccountNumber, C.VehicleNumber, C.ExpiryDate ,
case C.Status when 'E0' then 'Authorized' when 'E1' then 'Pending' end 'Status'
from #Temp T
inner join Card C on C.EmbossLine= T.EmbossLine
inner join Terminal on Terminal.TerminalID = T.TerminalID
inner join Merchant PM on PM.MerchantID = Terminal.MerchantID
inner join City on City.CityID = PM.CityID
inner join Country on Country.CountryID = PM.CountryID
where C.Status <>'E3'
and C.CardID not in (Select distinct isnull(CardID,0) from Testcards)
and (C.EmbossLine like '%'+#EmbossLine+'%' or #EmbossLine like '-999')
and (PM.CountryID = #CountryID or #CountryID ='-999')
and (C.Status = #status)
order by T.TransactionDate, MerchantName1, T.BatchNumber, T.SequenceNumber
End
Else
Begin
Select PT.[ID] 'TransactionID', PT.BatchNumber, PT.SequenceNumber, PT.TransactionDate,
PT.TerminalID, PT.TotalAmount, PT.TransactionTypeID, TT.TransactionType,PT.PAN 'EmbossLine',PT.PreBalanceAmount, PT.PostBalanceAmount, RefTxnID, SettlementDate,PaidCash, CreditAmount, DiscountAmount,
RefPAN, PT.Remarks, ' ' + CashierCard as 'SupervisorCard',St.StoreID
into #Temp
from POS_Transactions PT inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
inner join Staff St on St.CardNumber=PT.CashierCard
where PT.[ID] not in (Select distinct isnull(TransactionID,0) from Testcards) and (PT.TransactionDate >= #DateFrom) and (PT.TransactionDate < #DateTo)
and (PT.TransactionTypeID = 6) and (PT.BatchNumber = 0) and (Pt.SequenceNumber =-1)
select T.*, ' '+ C.EmbossLine+' ' as 'EmbossLine', C.EmbossLine as 'EmbossLine1',
isnull(C.FirstName,'') +' '+ isnull(C.LastName,'') 'EmbossName',C.FirstName,C.LastName,City.CityName,Country.CountryName,Country.CurrencyName, PM.MerchantID, PM.MerchantName1, C.AccountNumber, C.VehicleNumber, C.ExpiryDate ,
case C.Status when 'E0' then 'Authorized' when 'E1' then 'Pending' end 'Status'
from #Temp T
inner join Card C on C.EmbossLine= T.EmbossLine
inner join Terminal on Terminal.TerminalID = T.TerminalID
inner join Merchant PM on PM.MerchantID = Terminal.MerchantID
inner join City on City.CityID = PM.CityID
inner join Country on Country.CountryID = PM.CountryID
where C.Status <>'E3'
and C.CardID not in (Select distinct isnull(CardID,0) from Testcards)
and (C.EmbossLine like '%'+#EmbossLine+'%' or #EmbossLine like '-999')
and (PM.CountryID = #CountryID or #CountryID ='-999')
and (C.Status = #status)
order by T.TransactionDate, MerchantName1, T.BatchNumber, T.SequenceNumber
End
drop table #Temp
You cannot have two statements in the same procedure that creates a temp table with the same name. This is a leftover from SQL 6.5 which did not have deferred name resolution.
And in any case, it only makes sense if the tables are created exactly the same, else your procedure will behave very funky.
So instead of using SELECT INTO, use CREATE TABLE + INSERT.
UPDATE
According to the selected way from comment:
Second option: First create temp table and insert
First let's create the temp table. For that you should modify your procedure like:
create procedure spGetHOSalesReport
#DateFrom datetime,#DateTo datetime,#EmbossLine varchar(20),#CountryID int,#status char(2)
AS
BEGIN -- begin procedure
SET #DateTo = #DateTo +1
if object_id('tempdb..#Temp') is not null drop table #Temp
create table #Temp
( TransactionID int
, BatchNumber ... ( your type of field )
, SequenceNumber ...
, TransactionDate ...
, TerminalID int
, TotalAmount ...
, TransactionTypeID int
, TransactionType ...
, EmbossLine ...
, PreBalanceAmount ...
, PostBalanceAmount ...
, RefTxnID int
, SettlementDate ...
, PaidCash ...
, CreditAmount ...
, DiscountAmount ...
, RefPAN ...
, Remarks ...
, SupervisorCard ...
, StoreID int
)
if(#status = 'E1')
.......
I do not know which data type has these fields, so, you have to do yourself. Then edit insert into temp table in first case and similar in another case:
insert into #Temp
Select PT.[ID] 'TransactionID', PT.BatchNumber, PT.SequenceNumber, PT.TransactionDate,
PT.TerminalID, PT.TotalAmount, PT.TransactionTypeID, TT.TransactionType,PT.PAN 'EmbossLine',PT.PreBalanceAmount, PT.PostBalanceAmount, RefTxnID, SettlementDate,PaidCash, CreditAmount, DiscountAmount,
RefPAN, PT.Remarks, ' ' + CashierCard as 'SupervisorCard',St.StoreID
from TempPOS_Transactions PT inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
inner join Staff St on St.CardNumber=PT.CashierCard
where ...
In the end of procedure you can add:
End -- end of your if
if object_id('tempdb..#Temp') is not null drop table #Temp
END -- end of procedure
But the simplest way is create two different temp tables:
if(#status = 'E1')
begin
if object_id('tempdb..#Temp1') is not null drop table #Temp1
Select PT.[ID] 'TransactionID', PT.BatchNumber, ...
into #Temp1
from TempPOS_Transactions PT
inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
.....
end
else
begin
if object_id('tempdb..#Temp2') is not null drop table #Temp2
Select PT.[ID] 'TransactionID', PT.BatchNumber, ...
into #Temp2
from POS_Transactions PT
inner join TransactionType TT on TT.TransactionTypeID = PT.TransactionTypeID
....
end
Also, you can write just two select without creating temp table in this case
I am facing problem in merging results of two select queries
i have executed following code in sql, you may try
CREATE TABLE #a(a_id int, is_active bit, cr_date date)
CREATE TABLE #b(b_id int, a_id int, cr_date date)
INSERT INTO #a(a_id,is_active, cr_date)
VALUES(1,1,GETDATE()),(2,0,GETDATE()),(3,1,GETDATE()),(4,0,GETDATE()),(5,0,GETDATE())
INSERT INTO #b(b_id,a_id,cr_date)
VALUES(1,1,GETDATE()),(2,1,GETDATE()),(3,4,GETDATE()),(4,4,GETDATE()),(5,4,GETDATE()),(6,4,GETDATE())
CREATE TABLE #c(c_id int, is_active bit, cr_date date)
CREATE TABLE #d(d_id int, c_id int, cr_date date)
INSERT INTO #c(c_id,is_active, cr_date)
VALUES(1,1,GETDATE()),(2,0,GETDATE()),(3,1,GETDATE()),(4,0,GETDATE()),(5,0,GETDATE())
INSERT INTO #d(d_id,c_id,cr_date)
VALUES(1,1,GETDATE()),(2,1,GETDATE()),(3,4,GETDATE()),(4,4,GETDATE()),(5,4,GETDATE()),(6,4,GETDATE())
DECLARE #startDate date;
DECLARE #endDate date;
set #startDate='2012-10-26';
set #endDate=GETDATE();
SELECT
'#b= '+CAST(COUNT(b.b_id) AS VARCHAR) b_COUNT,
'#a = '+CAST(COUNT(a.a_id) AS VARCHAR) a_COUNT
FROM #a as a LEFT JOIN #b as b ON a.a_id = b.a_id AND a.is_active = 0
WHERE CONVERT(VARCHAR(10), a.cr_date, 111) BETWEEN #STARTDATE AND #ENDDATE
SELECT
'#d= '+CAST(COUNT(d.d_id) AS VARCHAR) d_COUNT,
'#c = '+CAST(COUNT(c.c_id) AS VARCHAR) c_COUNT
FROM #c as c LEFT JOIN #d as d ON c.c_id = d.c_id AND c.is_active = 0
WHERE CONVERT(VARCHAR(10), c.cr_date, 111) BETWEEN #STARTDATE AND #ENDDATE
for dropping tables
DROP TABLE #a
DROP TABLE #b
DROP TABLE #c
DROP TABLE #d
I got the following result of two select queries
Now, I want to merge both results of select queries, but i can't.
any one can tell me how can i merge both queries to get single results in output
You can use UNION or UNION ALL.
Example:
SELECT N'A' as col
UNION ALL
SELECT N'B' as col
You can use ALL to leave the results as they are. Even if there may be duplicates. ALL will be faster.
If you leave out ALL the query will be checked for duplicates.
Using UNION:
SELECT
'#b= '+CAST(COUNT(b.b_id) AS VARCHAR) b_COUNT,
'#a = '+CAST(COUNT(a.a_id) AS VARCHAR) a_COUNT
FROM #a as a LEFT JOIN #b as b ON a.a_id = b.a_id AND a.is_active = 0
WHERE CONVERT(VARCHAR(10), a.cr_date, 111) BETWEEN #STARTDATE AND #ENDDATE
UNION
SELECT
'#d= '+CAST(COUNT(d.d_id) AS VARCHAR) d_COUNT,
'#c = '+CAST(COUNT(c.c_id) AS VARCHAR) c_COUNT
FROM #c as c LEFT JOIN #d as d ON c.c_id = d.c_id AND c.is_active = 0
WHERE CONVERT(VARCHAR(10), c.cr_date, 111) BETWEEN #STARTDATE AND #ENDDATE
I'm quite a newbie in optimizing queries.. it would be a first for me to handle other persons query and optimize it to improve performance. Can you kindly give me advice on which part of the query could I simplify in order to improve its performance....
CREATE FUNCTION SALES
(#SUPPLIERCODE VARCHAR(15),
#BATCHID VARCHAR(50))
RETURNS
#STOCKDETAILS TABLE([ID] CHAR(1),
[BATCH RECEIVEDATE] DATETIME,
SUPPLIERCODE VARCHAR(15),
[NOW - RECEVEDATE] INT,
[DUEDATE] VARCHAR(50)
)
AS
BEGIN
DECLARE #RECEIVEDATE DATETIME,
#SUPPLIERCODE1 VARCHAR(15)
SELECT TOP 1
#RECEIVEDATE = O.ReceivedDate,
#SUPPLIERCODE1 = A.SUPPLIERCODE
FROM
TRANSACT.dbo.FIELDS A WITH(NOLOCK)
INNER JOIN
TRANSACT.dbo.DELIV O WITH(NOLOCK) ON O.BATCHID = A.BATCHID
DECLARE #ID1 TABLE(SUPPLIERCODE VARCHAR(50))
INSERT INTO #ID1
SELECT P.SUPPLIERCODE
FROM
(SELECT
[SUPPLIERCODE] = SUPPLIERCODE,
[TOTAL] = ISNULL(SUM(ITEMPRICE + (ITEMPRICE * .12)), 0)
FROM TRANSACT.dbo.ProviderDiscount WITH(NOLOCK)
WHERE ACQUIREDDATE <> '1900-01-01 00:00:00.000'
AND SUPPLIERCODE = #SUPPLIERCODE1
GROUP BY SUPPLIERCODE) P
WHERE P.TOTAL <> 0
DECLARE #ID TABLE ([BATCH RECEIVEDATE] DATETIME,
SUPPLIERCODE VARCHAR(15),
ACQUIREDDATE DATETIME,
Coverage VARCHAR(20),
CoverageItem VARCHAR(10),
[NOW - RECEVEDATE] INT,
DiscTerm1 INT, DiscTerm2 INT,
DiscTerm3 INT, DiscTerm4 INT,
DiscTerm5 INT,
[NEW ACQUIREDDATE] VARCHAR(50)
)
INSERT INTO #ID
SELECT DISTINCT
[BATCH RECEIVEDATE] = #RECEIVEDATE,
B.SUPPLIERCODE,
B.ACQUIREDDATE,
B.Coverage,
B.CoverageItem,
[NOW - RECEVEDATE] = DATEDIFF(DAY,#RECEIVEDATE,GETDATE()),
B.DiscTerm1, B.DiscTerm2, B.DiscTerm3,
B.DiscTerm4, B.DiscTerm5,
[NEW ACQUIREDDATE] = TRANSACT.dbo.fxnGetIDNewACQUIREDDATE(B.DiscTerm1, B.DiscTerm2, B.DiscTerm3, B.DiscTerm4, B.DiscTerm5, #RECEIVEDATE)
FROM
TRANSACT.dbo.ProviderDiscount B WITH(NOLOCK)
INNER JOIN
(SELECT
[ACQUIREDDATE] = MAX(ACQUIREDDATE),
[REOD] = MAX(REOD)
FROM
TRANSACT.dbo.ProviderDiscount B2 WITH(NOLOCK)
INNER JOIN
#ID1 B1 ON B1.SUPPLIERCODE = B2.SUPPLIERCODE
WHERE
B2.Coverage = #CLAIMTYPE
AND B2.ACQUIREDDATE < #RECEIVEDATE) B3 ON B3.REOD = B.REOD
INSERT INTO #STOCKDETAILS
SELECT DISTINCT
[ID] = 'Y',
[BATCH RECEIVEDATE],
SUPPLIERCODE,
[NOW - RECEVEDATE],
[DUEDATE] = MIN([NEW ACQUIREDDATE])
FROM
#ID
WHERE
ISNULL([NEW ACQUIREDDATE],'NONE') <> 'NONE'
GROUP BY
[BATCH RECEIVEDATE], SUPPLIERCODE, [NOW - RECEVEDATE]
RETURN
END
Well, here's one thing you can do.
DECLARE #ID1 TABLE(SUPPLIERCODE VARCHAR(50))
INSERT INTO #ID1
SELECT P.SUPPLIERCODE
FROM
(
SELECT
[SUPPLIERCODE] = SUPPLIERCODE,
[TOTAL] = ISNULL(SUM(ITEMPRICE+(ITEMPRICE*.12)),0)
FROM TRANSACT.dbo.ProviderDiscount WITH(NOLOCK)
WHERE ACQUIREDDATE <> '1900-01-01 00:00:00.000'
AND SUPPLIERCODE = #SUPPLIERCODE1
GROUP BY SUPPLIERCODE
) P
WHERE P.TOTAL <> 0
Can be rewritten stripped of lots of extra. Maybe even more than I do here:
DECLARE #ID1 TABLE(SUPPLIERCODE VARCHAR(50))
INSERT INTO #ID1
SELECT SUPPLIERCODE
FROM TRANSACT.dbo.ProviderDiscount WITH(NOLOCK)
WHERE ACQUIREDDATE <> '1900-01-01 00:00:00.000'
AND SUPPLIERCODE = #SUPPLIERCODE1
GROUP BY SUPPLIERCODE
HAVING ISNULL(SUM(ITEMPRICE),0) <> 0
This almost looks like test question for refactoring SQL.