Filter using NOT IN with more than one column - tsql

Is there a better way to write the following query to minimize code repetition in the WHERE statement?
SELECT TA.*
FROM TA
JOIN TB on TA.id = TB.id
JOIN TC on TB.id =TC.id
JOIN TD on TC.id = TD.id
JOIN TE on TD.id = TE.id
WHERE TC.Name NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)
AND TD.Name NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)
AND TE.Name NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)
Note: The filter is always the same: NOT IN (‘John’,’William’,’Jacob’,’Henry’,’David’)

Using exists with a table value constructor you can do something like this:
SELECT TA.*
FROM TA
JOIN TB on TA.id = TB.id
JOIN TC on TB.id =TC.id
JOIN TD on TC.id = TD.id
JOIN TE on TD.id = TE.id
WHERE NOT EXISTS (
SELECT 1
FROM (VALUES('John'),('William'),('Jacob'),('Henry'),('David')) V(name)
WHERE Name IN(TC.Name, TD.Name, TE.Name)
)

Related

Postgresql INTERSECT randomly not working

I've got a problem with the syntax of a SQL query. It works sometimes and sometimes not. It's defenitly a problem with the query.
An error at or near "INTERSECTSELECT".
SQL Error: 0, SQLState: 42601
SELECT DISTINCT s.id,
s.title,
s.question,
s.comments,
s.start_date,
s.end_date,
s.motivation,
s.goals,
s.method,
s.type,
s.channel,
s.rhythm,
s.sample
FROM study s
LEFT OUTER JOIN study_customer_information sci
ON sci.study_id = s.id
LEFT OUTER JOIN customer_information ci
ON ci.id = sci.customer_information_id
WHERE s.is_active = :isActive
AND
s.language = :language AND s.id IN (SELECT sci.study_id
FROM study_customer_information sci
INNER JOIN customer_information ci
ON ci.id = sci.customer_information_id
WHERE ci.name_de in (:customer_informations)
GROUP BY sci.study_id
HAVING COUNT(sci.study_id) = :number_customer_informations INTERSECT SELECT st.study_id
FROM study_touchpoint st
INNER JOIN touchpoint tp ON tp.id = st.touchpoint_id
INNER JOIN subject_area sa ON sa.id = tp.subject_area_id
WHERE sa.name_DE = :subject_areas_0 INTERSECT SELECT st.study_id
FROM study_touchpoint st
INNER JOIN touchpoint tp ON tp.id = st.touchpoint_id
INNER JOIN touch_point_type tpt ON tpt.id = tp.touch_point_type_id
WHERE tpt.name_DE = :touchpoint_types_0 INTERSECT SELECT sth.study_id
FROM study_theme sth
INNER JOIN theme th
ON th.id = sth.theme_id
WHERE th.name_de in (:themes)
GROUP BY sth.study_id
HAVING COUNT(sth.study_id) = :number_themes) ORDER BY s.title

Postgresql: UNION ALL on two queries using "with <name> as"?

I have this query:
with active_cars as (
select c.id
from car c
inner join dealership d on c.dealer_id = d.id and d.active=true and d.ownerId=${userId}
)
select cd.*
from car_details cd
inner join active_cars ac on cd.car_id = ac.id
where cd.ratings=5;
Then I have query:
with ports_active_cars as (
select c.id
from car c
inner join ports p on c.port_id = p.id and p.active=true and p.ownerId=${userId}
)
select cd.*
from car_details cd
inner join ports_active_cars pac on cd.car_id = pac.id
I'd like to know how I can combine the result of the two queries into one, so I get one result including all car_details records.
I tried this:
with active_cars as (
select c.id
from car c
inner join dealership d on c.dealer_id = d.id and d.active=true and d.ownerId=${userId}
)
select cd.*
from car_details cd
inner join active_cars ac on cd.car_id = ac.id
where cd.ratings=5
union all
with ports_active_cars as (
select c.id
from car c
inner join ports p on c.port_id = p.id and p.active=true and p.ownerId=${userId}
)
select cd.*
from car_details cd
inner join ports_active_cars pac on cd.car_id = pac.id;
but that is wrong, does not run.
Is there a way to combine the two into one result returning all rows of car_details?
You need to define both CTEs at the start of the statement:
with active_cars as (
select c.id
from car c
inner join dealership d
on c.dealer_id = d.id and d.active = true and d.ownerId = ${userId}
),
ports_active_cars as (
select c.id
from car c
inner join ports p
on c.port_id = p.id and p.active=true and p.ownerId = ${userId}
)
select cd.*
from car_details cd
inner join active_cars ac on cd.car_id = ac.id
where cd.ratings = 5
union all
select cd.*
from car_details cd
inner join ports_active_cars pac on cd.car_id = pac.id;

PostgreSQL Inner Join Where Get IDs of 3 Products

I have these 5 tables which is sale_order directly connected to sale_order_line that has the products of the order of course which is connected to product_product that is connected to product_template where a table called mrp_bom can connect to product template and a table connected to it which is bom_line. I am trying to Output the products that contain the word 836g
Here is what I have so far:
Select so.name,
pt.name,
sol.name
From sale_order so
Inner Join sale_order_line sol
On so.id = sol.order_id
Inner Join product_template pt
On sol.product_id = pt.id
Inner Join mrp_bom bom
On pt.id = bom.product_tmpl_id
Inner Join mrp_bom_line boml
On bom.id = boml.bom_id
Where boml.product_id = (Select id From product_template Where name Like '%836g%'
Order By so.name
This code outputs an error because I have 3 items with 836g. I tried changing the = in the condition into IN so it will grab all the ids it will return. But still it's giving me an error. This is the best I have so far, I have tried so many times, but I can't figure it out.
I have the feeling that something along these lines is what you actually want:
SELECT so.name,
pt.name,
sol.name
FROM sale_order so
INNER JOIN sale_order_line sol
ON so.id = sol.order_id
INNER JOIN product_template pt
ON sol.product_id = pt.id
INNER JOIN mrp_bom bom
ON pt.id = bom.product_tmpl_id
INNER JOIN mrp_bom_line boml
ON bom.id = boml.bom_id
WHERE pt.name LIKE '%836g%' -- just add a WHERE condition directly in your query
ORDER BY so.name
OMG! I just had the answer. I don't think this will help anyone but i'll post the answer i have
SELECT so.name,
pt.name PT,
sol.name SOL,
(Select pp1.name_template From product_product pp1 Where boml.product_id = pp1.id) BOML,
boml.product_id
FROM sale_order so
INNER JOIN sale_order_line sol
ON so.id = sol.order_id
INNER JOIN product_template pt
ON sol.product_id = pt.id
INNER JOIN mrp_bom bom
ON pt.id = bom.product_tmpl_id
INNER JOIN mrp_bom_line boml
ON bom.id = boml.bom_id
WHERE (Select pp1.name_template From product_product pp1 Where boml.product_id = pp1.id) LIKE '%836g%'
ORDER BY so.name
Thank you all for the effort of helping me! Great community we got here! :D

How to aggregate calculation in SQL Server?

I have a following script to get the total unit but it gives me an error
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
Do I need to calculate SUM(ta.Qty) outside the main table?
SELECT
ta.ProductName
, SUM(ta.Total)
, SUM(SUM(ta.Qty) * ta.Unit)
FROM
tableA tA
INNER JOIN
tableB tB on tA.ID = tb.TableAID
INNER JOIN
tableC tc on ta.ID = tc.TableAID
INNER JOIN
tableD td on td.ID = tb.TableBID
GROUP BY
ta.ProductName
Here is a query in the AdventureWorks database that produces the same error (but might make some sense):
SELECT v.Name AS Vendor, SUM(SUM(p.ListPrice*d.OrderQty)+h.Freight)
FROM Production.Product p
INNER JOIN Purchasing.PurchaseOrderDetail d ON p.ProductID = d.ProductID
INNER JOIN Purchasing.PurchaseOrderHeader h ON h.PurchaseOrderID = d.PurchaseOrderID
INNER JOIN Purchasing.Vendor v ON v.BusinessEntityID = h.VendorID
GROUP BY v.Name
And here are two ways that I could rewrite that query to avoid the error:
SELECT v.Name AS Vendor, SUM(x.TotalAmount+h.Freight)
FROM (
SELECT PurchaseOrderID, SUM(p.ListPrice*d.OrderQty) AS TotalAmount
FROM Production.Product p
INNER JOIN Purchasing.PurchaseOrderDetail d ON p.ProductID = d.ProductID
GROUP BY PurchaseOrderID
) x
INNER JOIN Purchasing.PurchaseOrderHeader h ON h.PurchaseOrderID = x.PurchaseOrderID
INNER JOIN Purchasing.Vendor v ON v.BusinessEntityID = h.VendorID
GROUP BY v.Name
SELECT v.Name AS Vendor, SUM(x.TotalAmount+h.Freight)
FROM Purchasing.PurchaseOrderHeader h
INNER JOIN Purchasing.Vendor v ON v.BusinessEntityID = h.VendorID
CROSS APPLY (
SELECT SUM(p.ListPrice*d.OrderQty) AS TotalAmount
FROM Production.Product p
INNER JOIN Purchasing.PurchaseOrderDetail d ON p.ProductID = d.ProductID
WHERE d.PurchaseOrderID=h.PurchaseOrderID
) x
GROUP BY v.Name
The first query uses derived tables and the second one uses CROSS APPLY.

I receive conversion varchar to float error when insert **set rowcount=1** in first line of code

I receive an error
Coversion of varchar to float
when I write
set rowcount = 1
on first line of my code.
My script is:
select
vh.VchNum, ct.Val, r.RoutSheetNo, vi.FinalQty,
rh.RequestNo, vh.VchDate,
p.PartCode, d.Title, co.val
from
inv.InvVchHdr vh
join
acc.DL d on d.AccNum = vh.DLREF
join
inv.InvVchItm vi on vi.VchHdrRef = vh.VchHdrID
join
inv.InvVchItmCtrl ct on ct.VchItmRef = vi.VchItmID
join
QCS.QcsCertificateOfAnalysis q on q.Number = ct.Val
join
USR.kalaf_info_p kp on kp.Id = q.QcsCertificateOfAnalysisId
join
USR.coil_trace co on co.id = kp.coil_id
join
inv.Part p on p.Serial = vi.PartRef
join
inv.InvRqstItm rq on rq.RqstItmID = vi.RefNum
join
inv.InvRqstHdr rh on rh.RqstHdrID = rq.HdrRef
join
PRD.vwPrdOrderItemPlan pl on rh.OrdPlnBase = pl.OrdPlnId
join
prd.prdroutsheet r on r.OrdPlnRef = pl.OrdPlnId
where
pl.pPartRef not in (select pipe_code from usr.pipe_kalaf)
and pl.pPartRef not in (select Serial from inv.Part where PartName like '%لاف%')
and vi.VchType = 57
union
select vh.VchNum,ct.Val,pl.OrdPlnNo
,vi.FinalQty,
rh.RequestNo,vh.VchDate,
p.PartCode,d.Title,co.val from
inv.InvVchHdr vh
join acc.DL d
on d.AccNum=vh.DLREF
join
inv.InvVchItm vi
on vi.VchHdrRef=vh.VchHdrID
join inv.InvVchItmCtrl ct
on ct.VchItmRef=vi.VchItmID
join QCS.QcsCertificateOfAnalysis q
on q.Number=ct.Val
join USR.kalaf_info_p kp
on kp.Id=q.QcsCertificateOfAnalysisId
join USR.coil_trace co
on co.id=kp.coil_id
join
inv.Part p
on p.Serial=vi.PartRef
join inv.InvRqstItm rq
on rq.RqstItmID=vi.RefNum
join inv.InvRqstHdr rh
on rh.RqstHdrID=rq.HdrRef
join PRD.vwPrdOrderItemPlan pl
on rh.OrdPlnBase=pl.OrdPlnId
where pl.pPartRef in (select pipe_code from usr.pipe_kalaf) and vi.VchType=57
SET ROWCOUNT 0
i use sql server 2000 and when I remove setrowcount statement, problem resolve.
please help me
Remove the =(equal) sign
from
set rowcount = 1
To
SET ROWCOUNT 1