how to delete the results of a complex query - sql

When I replace select * with delete I get a syntax error on line 2 near t. But I need that t, because I'm referencing it in the where clause. So how do I delete the results of this query?
select *
from [PrimusGroup].[dbo].[PrmsBlotter] t
where t.RunType = 'Backtesting'
and not exists (
select 1
from [PrimusGroup].[dbo].[PrmsBlotter] i
where i.RunType = 'Live'
and i.BBox = t.BBox
and convert(date,i.RunDateStart) = convert(date,t.TestDateFrom)
)

As #Gordon Linoff said, replace the select * with delete t.
delete t
from [PrimusGroup].[dbo].[PrmsBlotter] t
where t.RunType = 'Backtesting'
and not exists (
select 1
from [PrimusGroup].[dbo].[PrmsBlotter] i
where i.RunType = 'Live'
and i.BBox = t.BBox
and convert(date,i.RunDateStart) = convert(date,t.TestDateFrom)
)

Related

Converting a SQL SELECT query into a DELETE query

How would I turn this select query into a delete query? (deleting records from tbl_a_D_B_t_Items)
SELECT *
FROM
tbl_a_D_B_t_Items
LEFT JOIN
tbl_tr_D_Items
ON
tbl_a_D_B_t_Items.D_t_ItemID=tbl_tr_D_Items.D_t_ItemID
WHERE
(
tbl_tr_D_Items.D_t_ItemID
Is Null
)
;
DELETE X FROM tbl_a_D_B_t_Items X
LEFT JOIN
tbl_tr_D_Items Y
ON
X.D_t_ItemID=Y.D_t_ItemID
WHERE
(
Y.D_t_ItemID
Is Null
)
I would suggest not exists:
DELETE FROM tbl_a_D_B_t_Items a
WHERE NOT EXISTS (SELECT 1
FROM tbl_tr_D_Items d
WHERE a.D_t_ItemID = d.D_t_ItemID
);
Maybe this better:
DELETE FROM tbl_a_D_B_t_Items
WHERE D_t_ItemID NOT IN
( SELECT D_t_ItemID FROM tbl_tr_D_Items)

Subqueries in Python

I am trying to use subqueries to run matching against multiple tables and move the unmatched records to new table.
I have written SQL subqueries but the only issue i am facing is the performace, it is taking lot of time to process.
create table UnmatchedRecord
(select a.*
from HashedValues a
where a.Address_Hash not in(select b.Address_Hash
from HashAddress b)
and a.Person_Hash not in(select d.Person_Hash
from HashPerson d)
and a.HH_Hash not in(select f.HH_Hash
from HashHH f)
and a.VehicleRegistration not in(select VehicleRegistration
from MasterReference)
and a.EmailAddress not in (select EmailAddress
from MasterReference)
and a.PhoneNumber not in (select PhoneNumber
from MasterReference)
and a.NationalInsuranceNo not in (select NationalInsuranceNo
from MasterReference))
You can at least replace four subqueries with one:
select HashedValues.*
from HashedValues
where not exists (
select *
from MasterReference
where HashedValues.VehicleRegistration = MasterReference.VehicleRegistration
or HashedValues.EmailAddress = MasterReference.EmailAddress
or HashedValues.PhoneNumber = MasterReference.PhoneNumber
or HashedValues.NationalInsuranceNo = MasterReference.NationalInsuranceNo
)
and not exists (
select *
from HashAddress
where HashedValues.Address_Hash = HashAddress.Address_Hash
)
and not exists (
select *
from HashPerson
where HashedValues.Person_Hash = HashPerson.Person_Hash
)
and not exists (
select *
from HashHH
where HashedValues.HH_Hash = HashHH.HH_Hash
)

Errors usually but within EXISTS sub-query it runs

Is the following problematic?
DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE EXISTS
(
SELECT *
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
WHERE
b.[Past28Days] = 1 AND
a.[Index] = b.[Index]
HAVING SUM(b.Amount) = 0
)
Reason I'm slightly uneasy about using the above script is that if I run the following it errors:
SELECT *
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
WHERE
b.[Past28Days] = 1
HAVING SUM(b.Amount) = 0
I understand why this script errors => the select is not grouped on anything therefore the processor does not like the aggregation in the HAVING clause.
But as a sub-query this error does not occur - why? Is this a problematic approach?
EDIT
Ended up using the following:
DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE a.[Index] IN
(
SELECT [Index]
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData
WHERE [Past28Days] = 1
GROUP BY [Index]
HAVING SUM(Amount) = 0
)
But as suggested in answer the following is more readable by simply adding the GROUP BY into the sub-query:
DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
WHERE EXISTS
(
SELECT *
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
WHERE
b.[Past28Days] = 1 AND
a.[Index] = b.[Index]
GROUP BY b.[Index]
HAVING SUM(b.Amount) = 0
)
It is legal to omit group by and still perform aggregations, therefore having is still a way of limiting results:
select sum(x)
from
(
select 1 x union all select 2
) a
having sum(x) = 3
Exists() work because everything in select list is ignored. Exists() looks for rows only, and terminates as soon as one is found. You might add group by b.Index to make intent clear to anyone reviewing the code later, or rewrite it using inner join and derived table.
DELETE a
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData a
INNER JOIN
(
SELECT b.[Index]
FROM WHAnalysis.dbo.tb_r12027dxi_CalculatedData b
WHERE
b.[Past28Days] = 1
GROUP BY b.[Index]
HAVING SUM(b.Amount) = 0
) b1
ON a.[Index] = b1.[Index]

Exists in where clause return incorrect result

Please consider this Query:
SELECT tesd.State_Code,
tesd.City_Code,
tesd.Row_ID,
tesd.Qsno,
tesd.Total_Period,
tesd.Current_Period,
tesd.Week,
tesd.Block_No,
tesd.Family_ID,
tesd.Line_ID,
tesd.Page_ID
INTO #tmp
FROM Specification_Master tesm
INNER JOIN Specification_Details tesd
ON tesd.Master_Id = tesm.Id
WHERE tesm.[Year] = 2000
AND tesm.[Month] = 10
AND tesd.City_Code IN ('001')
I queried some data from 2 tables and insert them in #tmp .then I want to select data from 2 other tables and check one of that tables has values in #tmp tbale:
SELECT *
FROM tbl_Details D
INNER JOIN tbl_Master tem
ON D.ID_Master = tem.Id
WHERE D.Period <= 5
AND EXISTS (
SELECT Row_ID
FROM #tmp tm
WHERE tm.Current_Period > 1
AND tm.State_Code = tem.State_Code
AND tm.City_Code = tem.City_Code
AND tm.Qsno = tem.Qsno
)
AND D.[Status] > 2
when I run this query I got just one row but when I change EXISTS to NOT EXISTS I got more rows.I run this query seperatly :
SELECT Row_ID
FROM #tmp tm,tbl_Master tem
WHERE tm.Current_Period > 1
AND tm.Ostan_Code = tem.State_Code
AND tm.City_Code = tem.City_Code
AND tm.Porseshname_ID = tem.Qsno
and it returns 30 rows. Why Exists has this such behaivior ?
Exists returns a Boolean value based on the results of the subquery. It matters not if there are 1 or 30 rows returned. The number of rows you are retrieving is based on the select * statement, not the Exists clause.

SQL Server Where Clause Case Statement?

I have a Where Clause that checks the existence of rows in a subquery, but I only want to execute that check if a bit is set to 1. So for example:
Select * from Listing l
Where
l.IsDeleted=1
AND CASE WHEN #MustHasPicture = 1 THEN
(
EXISTS
(
SELECT NULL AS [EMPTY]
FROM [dbo].[ListingPictures] AS [lp]
INNER JOIN Listing l ON lp.ListingID=l.ID
)
)
ELSE 1 END = 1
This syntax is wrong, and I'm hoping someone can point me in the right direction. Thanks.
SELECT *
FROM Listing l
WHERE IsDeleted = 1
AND ( #MustHasPicture <> 1 OR
(#MustHasPicture = 1 AND l.id IN (
SELECT listingid
FROM ListingPictures
)
)
)
No need to do a case - if the first part of an and fails, the second part will not be performed.
select
*
from
Listing l
Where
l.IsDeleted = 1
and ((#MustHasPicture = 1 and exists (...)) or 1)
What about this one:
SELECT * FROM Listing l
WHERE l.IsDeleted = 1
AND (#MustHasPicture = 1
AND EXISTS(SELECT * FROM [dbo].[ListingPictures] AS [lp]
WHERE lp.ListingID = l.ID)
OR #MustHasPicture = 0)
But where does the Value #MustHasPicture come from?