Increase Open Query performance - sql-server

I have a small problem with this query. It returns me around 13k rows and takes around 12seconds or more.
SELECT
hla.Id,
hc.Nome AS Colaborador,
hla.UAP,
hra.Referencia,
hra.QtdAbastecimento,
hra.QtdPecasPorCaixa,
hra.QtdCaixas,
A.Etiqueta,
A.Localizacao
FROM
hListasAbastecimento hla
INNER JOIN hColaboradores hc
ON hc.Id = hla.ColaboradorId
INNER JOIN
hReferenciasAbastecimento hra
ON hla.Id = hra.ListaAbastecimentoId
LEFT JOIN OPENQUERY(MACPAC,
'SELECT
FET001.ET0102 AS Referencia,
FET001.ET0101 AS Etiqueta,
FET001.ET0109 AS Localizacao
FROM
AUTO.D805DATPOR.FET001 FET001
WHERE FET001.ET0104 = ''POE''
AND FET001.ET0105 = ''DIS''
ORDER BY FET001.ET0101 ASC ') A
ON A.Referencia = hra.Referencia
WHERE hla.Id = #Id
I'm not sure what can i do to increase the performance of this. I am already using the only primary key to link both tables. I also have no control over the linked server so i cannot create new indexes
UPDATE
I found out through a co-worker that there was a table on linked server that could help me get results by "UAP" which takes only 4 seconds just to get around 1700 rows which is what i needed
ALTER PROCEDURE GenerateListaAbastecimento
#Id INT,
#UAP NVARCHAR(20)
AS
BEGIN
CREATE TABLE #tempTable
(
Id INT PRIMARY KEY,
Referencia NVARCHAR(15),
Etiqueta INT,
Localizacao NVARCHAR(20)
UNIQUE(Id, Etiqueta)
)
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL ='INSERT INTO #tempTable
SELECT
Id,
Referencia,
Etiqueta,
Localizacao
FROM OPENQUERY(MACPAC,
''SELECT
ROW_NUMBER() OVER(ORDER BY FET001.ET0101 ASC) AS Id,
A.RH6001 as Referencia,
FET001.ET0101 AS Etiqueta,
FET001.ET0109 AS Localizacao
FROM AUTO.D805DATPOR.TRP060H AS A
LEFT JOIN AUTO.D805DATPOR.FET001 FET001
ON FET001.ET0102 = A.RH6001
AND FET001.ET0104 = ''''POE''''
AND FET001.ET0105 = ''''DIS''''
AND A.RH6002 = N''' + QUOTENAME(#UAP,N'''') + N''' '')'
EXEC sp_executesql #SQL
SELECT
hla.Id,
hc.Nome AS Colaborador,
hla.UAP,
hra.Referencia,
hra.QtdAbastecimento,
hra.QtdPecasPorCaixa,
hra.QtdCaixas,
A.Etiqueta,
A.Localizacao
FROM
hListasAbastecimento hla
INNER JOIN hColaboradores hc
ON hc.Id = hla.ColaboradorId
INNER JOIN
hReferenciasAbastecimento hra
ON hla.Id = hra.ListaAbastecimentoId
LEFT JOIN #tempTable A
ON A.Referencia = hra.Referencia
WHERE hla.Id = #Id
ORDER BY A.Etiqueta ASC
DROP TABLE #tempTable
END

Related

How to retrieve multiple items with all their attributes from an EAV data model?

How could someone retrieve multiple products with all their attributes whose ids are passed as a comma separated list to a stored procedure?
Tables are designed in a simple EAV fashion like so:
tbl_products
id
title
tbl_product_attributes
product_FK
attribute_FK
attribute_value
tbl_attributes
id
title
The following stored procedure do this for just one product:
CREATE PROCEDURE get_product
#product_id NVARCHAR(MAX)
AS
BEGIN
-- Create a temp table to store values of get_product_attributes sp
CREATE TABLE #temp ( attributes NVARCHAR(MAX) );
-- Insert results of get_product_attributes sp into temp table
INSERT INTO #temp (attributes)
EXEC get_product_attributes #product_id;
-- Select product with all its attributes
SELECT id,
title,
( SELECT attributes FROM #temp ) AS attributes
FROM tbl_products
WHERE id = #product_id;
END;
But what if we want multiple product details given the product ids?
(get_product_attributes stored procedure return all attributes and their values of a specific product as json it uses dynamic sql to retrieve all attributes then return them as json; exactly like what dynamic sql part of this answer does: https://stackoverflow.com/a/13092910/5048383)
(also using sql server 2016, got access to STRING_SPLIT function and could easily transform passed ids to rows)
Generally speaking, looping is bad in SQL. For what you described, I can't imagine why it would warrant a loop. However, here is a set based method with simple joins that would eliminate everything but a single procedure.
declare #tbl_products table (
id int,
title varchar(16))
insert into #tbl_products
values
(1,'prod1'),
(2,'prod2'),
(3,'prod3'),
(4,'prod4'),
(5,'prod5')
declare #tbl_attributes table (
id int,
title varchar(16))
insert into #tbl_attributes
values
(1,'attr1'),
(2,'attr2'),
(3,'attr3'),
(4,'attr4'),
(5,'attr5')
declare #tbl_product_attributes table (
product_FK int,
attribute_FK int,
attribute_value varchar(64))
insert into #tbl_product_attributes
values
(1,5,'blah'),
(1,3,'blah blah'),
(2,1,'not sure'),
(2,3,'what should be here'),
(2,4,'but here is a'),
(3,5,'line of text'),
(3,4,'as a place holder')
declare #product_id nvarchar(4000)
set #product_id = '1,3'
if object_id ('tempdb..#staging') is not null
drop table #staging
select
prod.id
,prod.title as ProductTitle
,'Attr' + cast(attr.id as char(8)) as AttributeID
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
into #staging
from
#tbl_products prod
inner join
#tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
#tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
inner join
string_split(#product_id,',') x
on x.value = prod.id
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME(AttributeID)
FROM (SELECT DISTINCT AttributeID FROM #staging) AS AttributeID
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'
SELECT ProductTitle, ' + #ColumnName + '
FROM #staging
PIVOT(min(AttributeTitle)
FOR AttributeID IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery
So, you would just create the proc on the top part...
create proc yourProc(#product_id nvarchar(4000))
as
select
prod.id
,prod.title as ProductTitle
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
from
#tbl_products prod
inner join
#tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
#tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
where
prod.id in (select * from string_split(#product_id,','))
NOTE: This can also be written more cleanly as a join
select
prod.id
,prod.title as ProductTitle
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
from
#tbl_products prod
inner join
#tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
#tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
inner join
string_split(#product_id,',') x
on x.value = prod.id

but give me error that invalid object name #temp2

Alter procedure spMRI_TAG_try
#DocNum int
as
declare #cnt int
declare #count int
declare #cardname nvarchar(100)
declare #Docdate datetime
declare #itemCode nvarchar(50)
declare #Dscription nvarchar(100)
declare #Quantity numeric(19,6)
declare #ManBtchNum char(1)
declare #SalPackUn numeric(19,6)
declare #ExpDate datetime
begin
set #cnt = 1
select #Count = pdn1.Quantity/OITM.SalPackUn from pdn1 inner join OITM on pdn1.ItemCode=OITM.ItemCode
while #cnt <= #count
insert into #temp2 values(#cardname,#DocDate,#itemcode,#Dscription,#Quantity,#ManBtchNum,#SalPackUn,#ExpDate)
select #cardname = a.CardName,#DocDate=a.DocDate,#itemcode=b.ItemCode,#Dscription=b.Dscription,#Quantity=b.Quantity,#ManBtchNum=c.ManBtchNum,#SalPackUn=c.SalPackUn,#ExpDate=d.ExpDate
from OPDN a inner join PDN1 b on a.DocEntry = b.DocEntry inner join OITM c on c.ItemCode = b.ItemCode inner join OBTN d on c.ItemCode = d.ItemCode and a.DocNum=#DocNum and d.ExpDate is not null
set #cnt=#cnt+1
end
select * from #temp2
but gives me an invalid object name #temp2 error.
Create temp table before your while loop:
create table #temp2 (Cardname ...)
while #cnt <= #count
insert into #temp2 values(#cardname,#DocDate,#itemcode,#Dscription,#Quantity,#ManBtchNum,#SalPackUn,#ExpDate)
select #cardname = a.CardName,#DocDate=a.DocDate,#itemcode=b.ItemCode,#Dscription=b.Dscription,#Quantity=b.Quantity,#ManBtchNum=c.ManBtchNum,#SalPackUn=c.SalPackUn,#ExpDate=d.ExpDate
Two points here:
Not sure why you are using looping - Try set based approaches. You can solve most of the problems in set based queries
You can create temp tables using select * into #temp2... Check for that syntax in msdn
To be honest your SP is a one big messed up code :)
I suggest you to rewrite it like this:
ALTER PROCEDURE spMRI_TAG_try
#DocNum int
AS
--Drop table if it exists
IF OBJECT_ID(N'#temp2') IS NOT NULL DROP TABLE #temp2
--create table
CREATE TABLE #temp2 (
cardname nvarchar(100),
Docdate datetime,
itemCode nvarchar(50),
Dscription nvarchar(100),
Quantity numeric(19,6),
ManBtchNum char(1),
SalPackUn numeric(19,6),
ExpDate datetime
)
--Make the insertion
INSERT INTO #temp2
SELECT a.CardName,
a.DocDate,
b.ItemCode,
b.Dscription,
b.Quantity,
c.ManBtchNum,
c.SalPackUn,
d.ExpDate
FROM OPDN a
INNER JOIN PDN1 b
ON a.DocEntry = b.DocEntry
INNER JOIN OITM c
ON c.ItemCode = b.ItemCode
INNER JOIN OBTN d
ON c.ItemCode = d.ItemCode and a.DocNum=#DocNum and d.ExpDate is not null
--output
SELECT *
FROM #temp2
No need a while loop (I can not even understand how you will switch through the rows, in your solution it will write the same row the '#count' times), you can write all data directly in temp table.
You get error because of there is no #temp2 table on the moment you are trying to insert, also there is no checking if the table already exists.
As was noted in answer by Kannan Kandasamy, the one more way is to use SELECT * INTO #temp2, it can be achieved this way:
ALTER PROCEDURE spMRI_TAG_try
#DocNum int
AS
IF OBJECT_ID(N'#temp2') IS NOT NULL DROP TABLE #temp2
SELECT a.CardName,
a.DocDate,
b.ItemCode,
b.Dscription,
b.Quantity,
c.ManBtchNum,
c.SalPackUn,
d.ExpDate
INTO #temp2
FROM OPDN a
INNER JOIN PDN1 b
ON a.DocEntry = b.DocEntry
INNER JOIN OITM c
ON c.ItemCode = b.ItemCode
INNER JOIN OBTN d
ON c.ItemCode = d.ItemCode and a.DocNum=#DocNum and d.ExpDate is not null
SELECT *
FROM #temp2

Not Exists not playing well with multiple columns

This has to be something simple that I have just missed...
I've got a temp table say this:
CREATE TABLE #tsa
(
AttendeeID int,
SurveyID int,
TrainingAttendeeID int
)
I get a single record using TOP 1 with something similar to this:
SELECT
TOP 1
#AttendeeID=ta.AttendeeID,
#SurveyID=ts.SurveyID,
#TrainingAttendeeID = ta.TrainingAttendeeID
FROM
TrainingAttendee ta
INNER JOIN
[User] u
ON
u.UserID= ta.AttendeeID
INNER JOIN
[Training] t
ON
t.TrainingID = ta.TrainingID
INNER JOIN
[TrainingSet] ts
ON
ts.TrainingSetID = t.TrainingSetID
WHERE
ta.AttendedTraining = 1
AND ta.ConfirmAttendedEmailOn IS NOT NULL
--only get people who didn't fill out the survey
AND NOT EXISTS (SELECT * FROM SurveyTaken st WHERE st.AddedByUserID = ta.AttendeeID AND st.SurveyID = ts.SurveyID)
ORDER BY
ta.AttendeeID,
ts.SurveyID
As soon as I get this one record I store it into my temp table as such:
--insert into our temp table
INSERT INTO #tsa(AttendeeID, SurveyID, TrainingAttendeeID)
VALUES(#AttendeeID, #SurveyID, #TrainingAttendeeID)
Then I need to go through this whole procedure of checking some data and sending an email...as soon as that email is sent I need to pick up the next record not including the record I had previously...So without showing too much code:
WHILE SomeCondition
BEGIN
--do some thing...
--pick up next one
--grab next one
SELECT
TOP 1
#AttendeeID = ta.AttendeeID,
#SurveyID=ts.SurveyID,
#TrainingAttendeeID=ta.TrainingAttendeeID
FROM
TrainingAttendee ta
INNER JOIN
[User] u
ON
u.UserID= ta.AttendeeID
INNER JOIN
[Training] t
ON
t.TrainingID = ta.TrainingID
INNER JOIN
[TrainingSet] ts
ON
ts.TrainingSetID = t.TrainingSetID
WHERE
(
--same where as original
ta.AttendedTraining = 1
AND (ta.ConfirmAttendedEmailOn IS NOT NULL)
AND (NOT EXISTS (SELECT * FROM SurveyTaken st WHERE st.AddedByUserID = ta.AttendeeID AND st.SurveyID = ts.SurveyID))
--adding the piece such that we compare against the temp table...
AND (NOT EXISTS (SELECT * FROM #tsa tempS WHERE tempS.AttendeeID = ta.AttendeeID AND tempS.SurveyID = ts.SurveyID AND tempS.TrainingAttendeeID = ta.TrainingAttendeeID))
)
ORDER BY
ta.AttendeeID,
ts.SurveyID
--insert into our temp table
INSERT INTO #tsa(AttendeeID, SurveyID, TrainingAttendeeID)
VALUES(#AttendeeID, #SurveyID, #TrainingAttendeeID)
END
Notice the where condition inside of this..I've added one more AND...namely:
--adding the piece such that we compare against the temp table...
AND (NOT EXISTS (SELECT * FROM #tSa tempS WHERE tempS.AttendeeID = ta.AttendeeID AND tempS.SurveyID = ts.SurveyID AND tempS.TrainingAttendeeID = ta.TrainingAttendeeID))
Just to ensure I am not reusing the record I already processed in my temp table...and you'll notice I reinsert into my temp table at the end as well...
--insert into our temp table
INSERT INTO #tsa(AttendeeID, SurveyID, TrainingAttendeeID)
VALUES(#AttendeeID, #SurveyID, #TrainingAttendeeID)
Every time I run this stored procedure it goes on infinitly and so I believe something is wrong with my condition at this point. I'm having a brain fart..or maybe there is just too much noise in the office. What am I missing here? I placed a print statement and it keeps processing the same record...so something tells me this last condition in my where clause is incorrect.
Edit
Here's the entire procedure...My issue is the record set only has one record in it...But the sproc continues to process this same record
PROCEDURE ScriptSendTrainingSurveyReminders
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #AttendeeID int
DECLARE #TrainingAttendeeID int
DECLARE #SurveyID int
DECLARE #Message nvarchar(MAX)
DECLARE #Subject nvarchar(255)
CREATE TABLE #tSa
(
AttendeeID int,
SurveyID int,
TrainingAttendeeID int
)
SELECT
TOP 1
#AttendeeID=ta.AttendeeID,
#SurveyID=ts.SurveyID,
#TrainingAttendeeID = ta.TrainingAttendeeID
FROM
TrainingAttendee ta
INNER JOIN
[User] u
ON
u.UserID= ta.AttendeeID
INNER JOIN
[Training] t
ON
t.TrainingID = ta.TrainingID
INNER JOIN
[TrainingSet] ts
ON
ts.TrainingSetID = t.TrainingSetID
WHERE
ta.AttendedTraining = 1
AND ta.ConfirmAttendedEmailOn IS NOT NULL
--only get people who didn't fill out the survey
AND NOT EXISTS (SELECT * FROM SurveyTaken st WHERE st.AddedByUserID = ta.AttendeeID AND st.SurveyID = ts.SurveyID)
ORDER BY
ta.TrainingAttendeeID,
ta.AttendeeID,
ts.SurveyID
--insert into our temp table
INSERT INTO #tSa(AttendeeID, SurveyID, TrainingAttendeeID)
VALUES(#AttendeeID, #SurveyID, #TrainingAttendeeID)
WHILE #TrainingAttendeeID IS NOT NULL AND #AttendeeID IS NOT NULL AND #SurveyID IS NOT NULL
BEGIN
DECLARE #TrainingID int
DECLARE #Title nvarchar(50)
DECLARE #StartDateTime nvarchar(50)
DECLARE #EndDateTime nvarchar(50)
DECLARE #FullName nvarchar(255)
DECLARE #EmailAddress nvarchar(255)
DECLARE #Description nvarchar(MAX)
--get the one record we are on...
SELECT
#TrainingID = t.TrainingID,
#Title = t.Title,
#StartDateTime = CAST(CONVERT(DATE, t.StartDate) AS VARCHAR(50)) + ' ' + CAST(t.StartTimeHours AS VARCHAR(50)) + ':' + CAST(CASE WHEN LEN(t.StartTimeMinutes)=1 THEN CAST(t.StartTimeMinutes AS VARCHAR(50)) + '0' ELSE CAST(t.StartTimeMinutes AS VARCHAR(50)) END AS VARCHAR(50)) + ' ' + CAST(t.StartTimeAMorPM AS VARCHAR(50)),
#EndDateTime = CAST(CONVERT(DATE, t.EndDate) AS VARCHAR(50)) + ' ' + CAST(t.EndTimeHours AS VARCHAR(50)) + ':' + CAST(CASE WHEN LEN(t.EndTimeMinutes)=1 THEN CAST(t.EndTimeMinutes AS VARCHAR(50)) + '0' ELSE CAST(t.EndTimeMinutes AS VARCHAR(50)) END AS VARCHAR(50)) + ' ' + CAST(t.EndTimeAMorPM AS VARCHAR(50)),
#Description = t.DescriptionHTML,
#FullName = u.FullName,
#EmailAddress = u.EmailAddress
FROM
Training t
INNER JOIN
TrainingAttendee ta
ON
t.TrainingID = ta.TrainingID
INNER JOIN
[User] u
ON
u.UserID = ta.AttendeeID
WHERE
ta.TrainingAttendeeID = #TrainingAttendeeID
IF #EmailAddress IS NOT NULL
BEGIN
--Email goes out here....
END
--grab next one
SELECT
TOP 1
#AttendeeID = ta.AttendeeID,
#SurveyID=ts.SurveyID,
#TrainingAttendeeID=ta.TrainingAttendeeID
FROM
TrainingAttendee ta
INNER JOIN
[User] u
ON
u.UserID= ta.AttendeeID
INNER JOIN
[Training] t
ON
t.TrainingID = ta.TrainingID
INNER JOIN
[TrainingSet] ts
ON
ts.TrainingSetID = t.TrainingSetID
WHERE
(
--same where as original
(ta.AttendedTraining = 1)
AND (ta.ConfirmAttendedEmailOn IS NOT NULL)
AND (NOT EXISTS (SELECT * FROM SurveyTaken st WHERE st.AddedByUserID = ta.AttendeeID AND st.SurveyID = ts.SurveyID))
--adding the piece such that we compare against the temp table...
AND (NOT EXISTS (SELECT * FROM #tSa tempS WHERE tempS.AttendeeID = ta.AttendeeID AND tempS.SurveyID = ts.SurveyID AND tempS.TrainingAttendeeID = ta.TrainingAttendeeID))
)
ORDER BY
ta.TrainingAttendeeID,
ta.AttendeeID,
ts.SurveyID
PRINT CAST('TrainingAttendeeID: ' + CAST(#TrainingAttendeeID as nvarchar(500)) + ' AttendeeID:' + CAST(#AttendeeID as nvarchar(500)) + ' SurveyID: ' + CAST(#SurveyID as nvarchar(500)) AS nvarchar(4000))
--insert into our temp table
INSERT INTO #tSa(AttendeeID, SurveyID, TrainingAttendeeID)
VALUES(#AttendeeID, #SurveyID, #TrainingAttendeeID)
END
END
GO
Variables will not change if select does not return any records. I bet it processes last #AttendeeID round and round.
Another way to test it - add unique constraint to temp table. I assume cycle will fail once there are no more records to select.
One way to fix it - assign NULLs to all variables at the beginning of each iteration (at the top of while body). But I'd recommend to rewrite this code to cursor if possible (not sure what is the logic of several select statements).
Note that declaration of variables within code block makes no "block-scope" sense since it is not perl or python.

selecting random records inside a UDF

I'm writing a function in sql server 2012.
I came to know that we can not use RAND() or NEWID() functions in the select statement of a function in sql server.
My function goes like this:
CREATE FUNCTION Keywordsuggester (#userid INT)
returns #suggestor_tab TABLE (
keywordid INT,
keywordname VARCHAR(max),
keywordcategory VARCHAR(max))
AS
BEGIN
DECLARE #category_table TABLE
(
category_name VARCHAR(max),
category_id INT,
rownum INT
)
DECLARE #ID INT = 1
DECLARE #COUNT INT = 0
DECLARE #I INT = 1
INSERT INTO #category_table
SELECT kc.NAME,
kc.id,
k.NAME,
d.NAME,
Row_number()
OVER(
ORDER BY d.id ASC) AS rownum
FROM dtypes d
JOIN keywords k
ON d.NAME LIKE '%' + k.NAME + '%'
JOIN keywordscategory kc
ON k.categoryid = kc.id
WHERE d.userid = #userid
SELECT #count = rownum
FROM #category_table
WHILE #count > #I
BEGIN
INSERT INTO #suggestor_tab
SELECT TOP 5 kc.id,
k.NAME,
kc.NAME
FROM kwords k
JOIN #category_table ct
ON k.categoryid = ct.category_id
JOIN kwcategory kc
ON kc.NAME = ct.category_name
WHERE ct.rownum = #I
--Here I'm inserting top 5 records for each category into the suggestor_tab,instead I have to insert random 5 records for each category(i.e.,#I)
SET #I=#I + 1
--return
END
INSERT INTO #suggestor_tab
SELECT kc.id,
k.NAME,
kc.NAME
FROM kwords k
JOIN #category_table ct
ON k.categoryid = ct.category_id
JOIN kwcategory kc
ON kc.NAME = category_name
RETURN
END
How can I get random records for each category(i.e., #I in the while loop).
I tried the query like:
SELECT TOP 5 k.NAME
FROM kwords k
JOIN #category_table ct
ON k.category_id = ct.id
JOIN kwcategory kc
ON kc.NAME = category_name
WHERE ct.rownum = #I
ORDER BY Newid()
which throws an error like:
Invalid use of a side-effecting operator 'newid' within a function.
Is there anyway to do this?
Thanks in advance.
You cannot use Non-deterministic Funcions inside UDF.
Create a View and use it in order by
create view Random
as
select newid() as New_id
Change you select something like this.
SELECT TOP 5 k.NAME
FROM KWords k
JOIN #category_table ct
ON k.category_id = ct.id
JOIN kwcategory kc
ON kc.NAME = category_name
WHERE ct.rownum = #I
ORDER BY (SELECT new_id
FROM random)

How to solve this variable pass into batch_date?

I want to pass in #batch date into batch_date...But it shows error...The error is
Column 'dbo.tnx_tid_InvCheck_Details.Batch_Date' is invalid in the
select list because it is not contained in either an aggregate
function or the GROUP BY clause.
The InvCheck_Details table has batch_date for each and every part_no. I want to group the part_no so that I can count(tid) and sum(tid_bal) by part_no. What should i do in order to run this script? TQ...
DECLARE #batch_date datetime
SET #batch_date = '2012-10-13 00:00:00.000'
CREATE TABLE #inv_check
(batch_date datetime,part_no varchar(25),Number_of_tid int,Updated_DT int, Tot_Tid_Bal int)
INSERT INTO #inv_check
SELECT batch_date,part_no,COUNT(tid)as Number_of_tid,0,sum(Tid_Bal)
FROM dbo.tnx_tid_InvCheck_Details
where batch_date = #batch_date
Group by part_no
order by part_no
UPDATE #inv_check
SET Updated_DT = isnull(d.Updated_DT,0)
--select i.part_no,i.Number_of_tid, isnull(d.Updated_DT,0)
FROM #inv_check i
LEFT OUTER JOIN
(SELECT part_no, COUNT(LastUpdate_DT)as Updated_DT,
sum(tid_bal) as Tid_bal_sum
FROM dbo.tnx_tid_InvCheck_Details
Where NOT LastUpdate_DT IS NULL
Group by part_no) d on i.part_no=d.part_no
DECLARE #sql int
DECLARE #sql1 int
SELECT #sql1 = count(part_no)
FROM #inv_check
SELECT #sql = count(part_no)
FROM #inv_check
WHERE number_of_tid= Updated_DT
SELECT #sql AS Parts_Counted,#sql1 AS Full_Parts
Drop table #inv_check
Try this
INSERT INTO #inv_check
Select y.batch_date,x.*
From dbo.tnx_tid_InvCheck_Details y
Join(
SELECT part_no,COUNT(tid)as Number_of_tid,0 AS Updated_DT,sum(Tid_Bal) As Tot_Tid_Bal
FROM dbo.tnx_tid_InvCheck_Details
where batch_date = #batch_date
Group by part_no
)x
On x.part_no = y.part_no
order by x.part_no

Resources