How to omit the table join based on some condition? - sql

=======================
SELECT *
FROM PRODUCT P
JOIN PRODUCT_LOC PL
ON P.PRODUCT_ID = PL.PRODUCT_ID
JOIN PRODUCT_LOC_DEF PLD AND PL.LOC_ID = PLD.LOC_ID
JOIN PRODUCT_CURRENT_LOC PCL
ON PLD.LOC_ID = PCL.LOC_ID AND P.PRODUCT_ID = PCL.PRODUCT_ID
How should I modify the query to get expected result in case 1 and case 2 as given in attached snapshot?
Preferred:
I am looking for the modification in the same query instead of making two query and union them.

Just use a left join instead of an inner join:
SELECT *
FROM PRODUCT P
LEFT JOIN PRODUCT_LOC PL ON P.PRODUCT_ID = PL.PRODUCT_ID
LEFT JOIN PRODUCT_LOC_DEF PLD AND PL.PRODUCT_LOC_ID = PLD.LOC_ID
LEFT JOIN PRODUCT_CURRENT_LOC PCL ON PLD.LOC_ID = PCL.LOC_ID

You should try this:
SELECT * FROM
PRODUCT p
INNER JOIN
PRODUCT_CURRENT_LOC pcl
ON
p.PRODUCT_ID = pcl.PRODUCT_ID
INNER JOIN
PRODUCT_LOC pc
ON
pc.LOC_ID = pcl.LOC_ID
UNION
SELECT * FROM
PRODUCT p
LEFT OUTER JOIN
PRODUCT_CURRENT_LOC pcl
ON
p.PRODUCT_ID = pcl.PRODUCT_ID
AND
pcl.PRODUCT_ID IS NULL
LEFT OUTER JOIN
PRODUCT_LOC pc
ON
pc.LOC_ID = pcl.LOC_ID
AND
pc.LOC_ID IS NULL

Related

Best Join Strategy/Indexes for SQL Server

What is the best join strategy/indexes for this query:
SELECT
kwk.*, an.AuftragDatum, an.AbgabeDatum, an.BezahltDatum, an.AuftragStatus
FROM
KundenWerbenKunden kwk
INNER JOIN
Auftrag an ON an.AuftragNummer = kwk.AuftragNummer
WHERE
kwk.Deleted = 0
Table KundenWerbenKunden has 103950 rows with 103646 Deleted = 0 ones.
Table Auftrag has 3826552 rows.
In my real query I make some more joins:
INNER JOIN
Filiale fn WITH (NOLOCK) ON an.FilialeID = fn.FilialeID
INNER JOIN
Kunde kn ON an.KundeID = kn.KundeID
OUTER APPLY
(SELECT DISTINCT KSKNr
FROM KdZuordnung
WHERE KundeID = kn.KundeID) zn
LEFT JOIN
Anrede ann WITH (NOLOCK) ON kn.Anrede = ann.Anrede
INNER JOIN
AuftragArt aa WITH (NOLOCK) ON an.AuftragArtID = aa.AuftragArtID
INNER JOIN
AuftragGrund ag WITH (NOLOCK) ON an.AuftragGrundID = ag.AuftragGrundID
INNER JOIN
AuftragType at WITH (NOLOCK) ON an.AuftragTypeID = at.AuftragTypeID
For this query:
SELECT *
FROM KundenWerbenKunden kwk INNER JOIN
Auftrag an
ON an.AuftragNummer = kwk.AuftragNummer
WHERE kwk.Geloescht = 0;
And not knowing anything about the distribution of Geloescht, I would first try indexes on KundenWerbenKunden(Geloescht, AuftragNummer) and Auftrag(AuftragNummer).

Duplicate data from select statement

I want to make a stress test to a procedure than generate a .csv file.
The problem is that i have not enough data, so i want to duplicate data in my sql select .
The query look like this:
SELECT P.FST_NAME,
P.LAST_NAME,
P.EMAIL_ADDR,
P.PERSON_UID,
PR.FST_NAME PRSP_FST_NAME,
PR.LAST_NAME PRSP_LAST_NAME,
M.X_BAPRO_DT_01,
M.X_BAPRO_DT_02,
M.X_BAPRO_DT_03,
M.X_BAPRO_MONTO,
M.X_BAPRO_NUM_01,
M.X_BAPRO_NUM_02,
M.X_BAPRO_NUM_03,
M.X_BAPRO_TEXT_01,
M.X_BAPRO_TEXT_02,
M.X_BAPRO_TEXT_03,
M.X_BAPRO_TEXT_04,
M.X_BAPRO_TEXT_05
FROM SIEBEL.S_SRC C
left join SIEBEL.S_CAMP_CON M on C.ROW_ID = M.SRC_ID
left join SIEBEL.S_DMND_CRTN_PRG T on T.ROW_ID = M.DCP_ID
left join SIEBEL.S_CONTACT P on P.ROW_ID = M.CON_PER_ID
left join SIEBEL.S_PRSP_CONTACT PR on PR.ROW_ID= M.PRSP_CON_PER_ID
WHERE
C.ROW_ID <> p_row_id
So, This query return about 100 records, i want to retrive 1000 records and i dont really care if the data is duplicated.
You can add a cross join:
FROM SIEBEL.S_SRC C
left join SIEBEL.S_CAMP_CON M on C.ROW_ID = M.SRC_ID
left join SIEBEL.S_DMND_CRTN_PRG T on T.ROW_ID = M.DCP_ID
left join SIEBEL.S_CONTACT P on P.ROW_ID = M.CON_PER_ID
left join SIEBEL.S_PRSP_CONTACT PR on PR.ROW_ID= M.PRSP_CON_PER_ID
cross join (select 1 as n from dual union all
select 2 from dual
. . .
) x
You can also use the VALUE clause to construct the little "muliplier"-table as shown below:
SELECT ...
FROM SIEBEL.S_SRC C
left join SIEBEL.S_CAMP_CON M on C.ROW_ID = M.SRC_ID
left join SIEBEL.S_DMND_CRTN_PRG T on T.ROW_ID = M.DCP_ID
left join SIEBEL.S_CONTACT P on P.ROW_ID = M.CON_PER_ID
left join SIEBEL.S_PRSP_CONTACT PR on PR.ROW_ID= M.PRSP_CON_PER_ID
cross join (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) tabl(n)

IN Linux Distinct SQL is not working with UNNEST

When i run this query in window system behave correctly UNNSET
but when i run this query Linux behave different.unnset duplicate record list on different row
SELECT DISTINCT
"billing_billmanagement"."creation_date",
"billing_billmanagement"."bill_number",
unnest(array_agg(DISTINCT "inventory_product"."product_name")) AS "product",
unnest(array_agg(DISTINCT "services_service"."name")) AS "service"
FROM "billing_billmanagement"
INNER JOIN "users_staffuser" ON ("billing_billmanagement"."staff_id" = "users_staffuser"."id")
INNER JOIN "auth_user" ON ("users_staffuser"."user_id" = "auth_user"."id")
LEFT OUTER JOIN "billing_customerproductbill" ON ("billing_billmanagement"."id" = "billing_customerproductbill"."bill_id")
LEFT OUTER JOIN "inventory_product" ON ("billing_customerproductbill"."product_id" = "inventory_product"."id")
LEFT OUTER JOIN "billing_customerservicebill" ON ("billing_billmanagement"."id" = "billing_customerservicebill"."bill_id")
LEFT OUTER JOIN "services_service" ON ("billing_customerservicebill"."service_id" = "services_service"."id")
WHERE "billing_billmanagement"."creation_date" BETWEEN '2017-12-04' AND '2017-12-06'
GROUP BY billing_billmanagement.creation_date,
billing_billmanagement.bill_number
ORDER BY "billing_billmanagement"."creation_date" ASC
If getting duplicate rows is the problem, try this
SELECT billing_billmanagement.creation_date,
billing_billmanagement.bill_number,
inventory_product.product_name AS product,
services_service.name AS service
FROM billing_billmanagement
INNER JOIN users_staffuser ON (billing_billmanagement.staff_id = users_staffuser.id)
INNER JOIN auth_user ON (users_staffuser.user_id = auth_user.id)
LEFT OUTER JOIN billing_customerproductbill ON (billing_billmanagement.id = billing_customerproductbill.bill_id)
LEFT OUTER JOIN inventory_product ON (billing_customerproductbill.product_id = inventory_product.id)
LEFT OUTER JOIN billing_customerservicebill ON (billing_billmanagement.id = billing_customerservicebill.bill_id)
LEFT OUTER JOIN services_service ON (billing_customerservicebill.service_id = services_service.id)
WHERE billing_billmanagement.creation_date BETWEEN '2017-12-04' AND '2017-12-06'
GROUP BY 1,
2,
3,
4
ORDER BY 1 ASC;

How to select top when already selected fields

Just wanted to ask how to add a 'select top 1 *' when I've already selected fields from a list? I seen examples in other codes but don't quite get it. Thought will be easier if see it in a code I constructed.
Below is an example of a query I have:
select frp.ProductPersonID,frp.FlightSeatId, frp.PlusMealId, per.TitleID, per.surname, per.FirstName, per.PersonTypeId, tor.PersonID, tor.Reference
from package pk
inner join product p on p.packageid = pk.packageid
inner join productperson pp on pp.productid = p.productid
inner join person per on per.personid = pp.personid
left join flightlogicalseat fls on fls.productpersonid = pp.productpersonid
inner join TourOperatorReference tor on tor.PersonID = per.PersonId
inner join FlightReservationPassenger frp on frp.ProductPersonID = pp.ProductPersonId
where pk.Reference LIKE '%'
and ProductTypeId =1
Simply try to use TOP keyword like this:
select TOP 1 frp.ProductPersonID,frp.FlightSeatId, frp.PlusMealId, per.TitleID,
You can just wrap your existing query in new query:
SELECT TOP 1 * FROM
(select frp.ProductPersonID,frp.FlightSeatId, frp.PlusMealId, per.TitleID, per.surname, per.FirstName, per.PersonTypeId, tor.PersonID, tor.Reference
from package pk
inner join product p on p.packageid = pk.packageid
inner join productperson pp on pp.productid = p.productid
inner join person per on per.personid = pp.personid
left join flightlogicalseat fls on fls.productpersonid = pp.productpersonid
inner join TourOperatorReference tor on tor.PersonID = per.PersonId
inner join FlightReservationPassenger frp on frp.ProductPersonID = pp.ProductPersonId
where pk.Reference LIKE '%'
and ProductTypeId =1) t

Sql Not Compiling Error

i have the above SQL query is not compiling somewhere i lost a truck if you please help me locate the error.
SELECT *
FROM tblWarehouse AS W INNER JOIN (((tblTransactionsSC AS T
LEFT JOIN tblCustomer AS C ON T.tracstID = C.cstID)
INNER JOIN (tblTransactionsSubSC AS TS
LEFT JOIN tblWarehouseItem AS WI
ON TS.trswhiID = WI.whiID)
ON T.traID = TS.trstraID)
ON W.wrhID = T.trawrhID)
LEFT JOIN tblTransactionsSC ON tblStockItemAssignment.siaID = tblTransactionsSC.trasiaID
Your JOIN ON clauses are going haywire; try placing them properly like
SELECT w.*
FROM tblWarehouse AS W
INNER JOIN tblTransactionsSC AS T ON W.wrhID = T.trawrhID
LEFT JOIN tblCustomer AS C ON T.tracstID = C.cstID
INNER JOIN tblTransactionsSubSC AS TS ON T.traID = TS.trstraID
LEFT JOIN tblWarehouseItem AS WI ON TS.trswhiID = WI.whiID
LEFT JOIN tblTransactionsSC ON tblStockItemAssignment.siaID = tblTransactionsSC.trasiaID