how to join two tables where second table has condtion - sql

I have two tables like
shopping_cart_table and customer_table
shopping_cart_table has fields shoppingcart_id | home_No|
customer_table has fields shoppingcart_id | status| customer_type|
I want to get the home_No from shopping_cart_table WHERE (customer_table.status is null OR customer_table.status='Y') AND customer_table.customer_type='X'
both table can join from shoppingcart_id

Actually this is just basic.
You can use join & put where conditions.
Select a.home_No
from shopping_cart_table as a
inner join customer_table as b
on a.shoppingcart_id = b.shoppingcart_id
where nvl(b.status,'Y') = 'Y'
and customer_type='X'

select home_No
from shopping_cart_table, customer_table
WHERE shopping_cart_table.shoppingcart_id = customer_table.shoppingcart_id
AND(customer_table.status is not null OR customer_table.status='Y') AND
customer_table.customer_type='X'
But this condition looks a bit strange:
(customer_table.status is not null OR customer_table.status='Y')
Maybe you'd want to change it for
nvl(customer_table.status,'Y')='Y'
aqssuming that 'not' was put there by a mistake

You can try this query:
SELECT sct.home_no
FROM shopping_cart_table AS sct
, customer_table AS ct
WHERE sct.shoppingcart_id = ct.shoppingcart_id
AND (
ct.status IS NOT NULL
OR ct.status = 'Y')
AND ct.customer_type = 'X'

Related

SQL Query to apply join on basis of case Condition

I have a requirement where I need to fetch the Dimension Key of Region table on basis of the following preference.
Fetch dimension key on basis of Zipcode of Physical address(PA)
If the first condition is not satisfied that fetch dimension key on basis of the Zip Code of the Mailing address
If the second condition is also not satisfied than fetch the dimension key on basis of the Parish Code of Physical address
Else fetch dimension key on basis of parish Code of Mailing address.
I am trying to use the below query but is giving multiple records since all left joins are getting evaluated. I want that it should not go on the second condition if the first condition is satisfied.
select REGION_DIM_SK, CASE_NUM
from (
select distinct COALESCE(RDIM.REGION_DIM_SK, RDIM1.REGION_DIM_SK, RDIM2.REGION_DIM_SK, RDIM3.REGION_DIM_SK) AS REGION_DIM_SK
, DC.CASE_NUM, ADDR_TYPE_CD
FROM rpt_dm_ee_intg.CASE_PERSON_ADDRESS dc
left join rpt_dm_ee_prsnt.REGION_DIM RDIM on dc.ZIP_CODE = RDIM.ZIP_CODE and RDIM.REGION_EFF_END_DT IS NULL and dc.addr_type_cd='PA' AND dc.EFF_END_DT IS NULL
left join rpt_dm_ee_prsnt.REGION_DIM RDIM1 ON dc.ZIP_CODE = RDIM1.ZIP_CODE AND RDIM1.REGION_EFF_END_DT IS NULL AND dc.addr_type_cd='MA' AND DC.EFF_END_DT IS NULL
left join (
select PARISH_CD, min(REGION_DIM_SK) as REGION_DIM_SK
from rpt_dm_ee_prsnt.REGION_DIM
where REGION_EFF_END_DT is null
group by PARISH_CD
) RDIM2 ON dc.addr_type_cd='PA' and dc.PARISH_CD = RDIM2.PARISH_CD AND DC.EFF_END_DT IS NULL
left join (
select PARISH_CD, min(REGION_DIM_SK) as REGION_DIM_SK
from rpt_dm_ee_prsnt.REGION_DIM
where REGION_EFF_END_DT is null
group by PARISH_CD
) RDIM3 ON dc.addr_type_cd='MA' and dc.PARISH_CD = RDIM3.PARISH_CD AND DC.EFF_END_DT IS NULL
) A
where REGION_DIM_SK is not null
) RD on RD.case_num = rpt_dm_ee_intg.CASE_PERSON_ELIGIBILITY.CASE_NUM
Use multiple left joins. Your query is rather hard to follow -- it has other tables and references not described in the problem.
But the idea is:
select t.*,
coalesce(rpa.dim_key, rm.dim_key, rpap.dim_key, rmp.dim_key) as dim_key
from t left join
dim_region rpa
on t.physical_address_zipcode = rpa.zipcode left join
dim_region rm
on t.mailing_address_zipcode = rm.zipcode and
rpa.zipcode is null left join
dim_region rpap
on t.physical_addresss_parishcode = rpap.parishcode and
rm.zipcode is null left join
dim_region rmp
on t.physical_addresss_parishcode = rmp.parishcode and
rpap.zipcode is null
The trick is to put the conditions in CASE WHEN:
SELECT *
FROM table1 a
JOIN table2 b
ON CASE
WHEN a.code is not null and a.code = b.code THEN 1
WHEN a.type = b.type THEN 1
ELSE 0
END = 1
For your example you can reduce the code to just two joins, it can't be done in one as you are joining two different tables.
SELECT CASE WHEN RDIM.addres IS NULL THEN RDIM2.addres ELSE RDIM.addres
FROM rpt_dm_ee_intg.CASE_PERSON_ADDRESS dc
LEFT JOIN rpt_dm_ee_prsnt.REGION_DIM RDIM ON CASE
WHEN (dc.ZIP_CODE = RDIM.ZIP_CODE
AND RDIM.REGION_EFF_END_DT IS NULL
AND dc.addr_type_cd='PA'
AND dc.EFF_END_DT IS NULL) THEN 1
WHEN (dc.ZIP_CODE = RDIM1.ZIP_CODE
AND RDIM1.REGION_EFF_END_DT IS NULL
AND dc.addr_type_cd='MA'
AND DC.EFF_END_DT IS NULL) THEN 1
ELSE 0
END = 1
LEFT JOIN
(SELECT PARISH_CD,
min(REGION_DIM_SK) AS REGION_DIM_SK
FROM rpt_dm_ee_prsnt.REGION_DIM
WHERE REGION_EFF_END_DT IS NULL
GROUP BY PARISH_CD) RDIM2 ON CASE
WHEN (dc.addr_type_cd='PA'
AND dc.PARISH_CD = RDIM2.PARISH_CD
AND DC.EFF_END_DT IS NULL
AND RDIM.ZIP_CODE IS NULL) THEN 1
WHEN (dc.addr_type_cd='MA'
AND dc.PARISH_CD = RDIM3.PARISH_CD
AND DC.EFF_END_DT IS NULL
AND RDIM.ZIP_CODE IS NULL) THEN 1
ELSE 0
END = 1
edit
If you don't want to have nulls from RDIM2 table if RDIM1 zip code is present the logic could be easily extended to support that. You just need to add AND RDIM.ZIP_CODE IS NULL to CASE WHEN conditions.

SQL Combining Two Totally seperate tables to one

I am VERY new to SQL and self taught. I have two SQL that I stuggled through but got working. Now I need to combine them into one and I'm lost.
SELECT
s.lastfirst,
s.student_number,
SUM(tr.howmany)
FROM
students s
JOIN
truancies tr ON s.id = tr.studentid
WHERE
s.enroll_status = 0 AND
s.schoolid = ~(curschoolid)
GROUP BY
s.lastfirst, s.student_number
HAVING
SUM(tr.howmany) > 0
ORDER BY
s.lastfirst
And this table:
SELECT
S.DCID as DCID,
S.LASTFIRST as LASTFIRST,
S.STUDENT_NUMBER as STUDENT_NUMBER,
S2.FC_SRVC_HRS_DUE as FC_SRVC_HRS_DUE,
CASE
WHEN S2.FC_SRVC_HRS_COMPLETED IS NULL
THEN '0'
ELSE S2.FC_SRVC_HRS_COMPLETED
END AS FC_SRVC_HRS_COMPLETED,
S2.FC_SRVC_HRS_BUYOUT as FC_SRVC_HRS_BUYOUT,
CASE
WHEN S2.FC_SRVC_HRS_COMPLETED IS NULL
THEN S2.FC_SRVC_HRS_DUE * S2.FC_SRVC_HRS_BUYOUT
ELSE ((S2.FC_SRVC_HRS_DUE - S2.FC_SRVC_HRS_COMPLETED) * S2.FC_SRVC_HRS_BUYOUT)
END as Balance_Due
FROM
STUDENTS S, U_STUDENTSUSERFIELDS S2
WHERE
S.DCID = S2.STUDENTSDCID AND
s.enroll_status = 0 AND
s.schoolid = ~(curschoolid) AND
(((S2.FC_SRVC_HRS_DUE - S2.FC_SRVC_HRS_COMPLETED) * S2.FC_SRVC_HRS_BUYOUT) > 0 OR
((S2.FC_SRVC_HRS_DUE - S2.FC_SRVC_HRS_COMPLETED) * S2.FC_SRVC_HRS_BUYOUT) IS NULL) AND
S2.FC_SRVC_HRS_DUE >.1
ORDER BY
s.lastfirst
What I am really looking for are the totals of both of these. I want the SUM(tr.howmany) from the first table and the balance due of the second BUT I need the filters that are in there. This would be sorted by student. I hope I am making sense. Any assistance would be appreciated.
You can join together 2 separate SQL select statements:
Eg:
Select A.id, A.value, B.value
From (select id, count(*) as value from TableA ...) AS A
join (select id, sum(field) as value from TableB ...) AS B
on A.id = B.id
order by A.id
As long as you have a common field to join on this would work. In your case the student_number looks like a good candidate. You will have to do the ordering outside of your subqueries.

Query table with all names in one statement

I have a table that I cannot alter and I am trying to wrap my head around an appropriate way to query this table in one statement based on one given value.
Roughly here's what the table looks like:
What I'm after is a way to query the table using only the SubBody code in order to get all names associated with it.
for example,
<query> where SubBody = '1001'
returns
| HName | HSName | BName | BSName |
+-----------------------------------+
| Toys | Sport | Ball | Baseball |
SELECT Head.Name as HName ,
SubHead.Name as HSName ,
Body.Name as BName ,
SubBody.Name as BSName
FROM yourTable as SubBody
JOIN yourTable as Body
ON SubBody.Body = Body.Body
AND Body.SubBody IS NULL
JOIN yourTable as SubHead
ON Body.SubHead = SubHead.SubHead
AND SubHead.Body IS NULL
JOIN yourTable as Head
ON SubHead.Head = Head.Head
AND Head.SubHead IS NULL
WHERE SubBody.SubBody = '1001'
Although you can express the logic as joins, for some reason correlated subqueries come to mind first:
select (select th.name from t th where th.head = t.head and th.subhead is null) as hname,
(select ts.name from t ts where ts.head = t.head and ts.subhead = t.subhead and t.body is null) as sname,
(select tb.name from t tb where tb.head = t.head and tb.subhead = t.subhead and tb.body = t.body and tb.subbody is null) as bname,
t.name as bsname
from t
where t.subbody = 1001
This answer is close to what Juan Carlos has posted. Which one you like depends a bit on your style.
WITH BaseRecord AS(
SELECT *
FROM ToyTable
WHERE SubBody = '1001'
)
SELECT
h.Name AS HName,
hs.Name AS HSName,
b.Name AS BName,
bs.Name AS BSName
FROM BaseRecord bs
INNER JOIN ToyTable b ON bs.Body = b.Body AND ISNULL(b.SubBody,'') = ''
INNER JOIN ToyTable hs ON bs.SubHead = hs.SubHead AND ISNULL(hs.Body,'') = ''
INNER JOIN ToyTable h ON bs.Head = h.Head AND ISNULL(h.SubHead,'') = ''
I'm not sure whether your "empty" cells contain nulls or empty strings. Either way, both are taken into account here.

Null value not getting picked in coalesce sql

I have created a query to fetch values from mapping staging table for location and job code
SELECT ORG_NAME,
COALESCE(JOB_MAP.FUSION_HARMONIZED_CODE,JOB_CODE) JOB_CODE,
JOB_SET_CODE,
COALESCE(LOC_MAP.FUSION_HARMONIZED_CODE,LOCATION_CODE)LOCATION_CODE
FROM XX_POS POS_STAG,
XX_MAP JOB_MAP,
XX_MAP LOC_MAP
WHERE JOB_MAP.SOURCE_CORE_HR_CODE(+)= POS_STAG.JOB_CODE
AND JOB_MAP.TABLE_CODE(+) ='JOB'
AND POS_STAG.BUSINESS_UNIT_NAME =JOB_MAP.business_unit
AND LOC_MAP.TABLE_CODE(+) ='LOC'
AND LOC_MAP.SOURCE_CORE_HR_CODE(+) = POS_STAG.LOCATION_CODE
AND POS_STAG.BUSINESS_UNIT_NAME =LOC_MAP.BUSINESS_UNIT;
But this query is not picking up value for location_code which is null in xx_pos table. Do i have to change my where condition ?
I think this is the query you want:
SELECT ORG_NAME,
COALESCE(JOB_MAP.FUSION_HARMONIZED_CODE, JOB_CODE) as JOB_CODE,
JOB_SET_CODE,
COALESCE(LOC_MAP.FUSION_HARMONIZED_CODE, LOCATION_CODE) as LOCATION_CODE
FROM XX_POS POS_STAG LEFT JOIN
XX_MAP JOB_MAP
ON JOB_MAP.SOURCE_CORE_HR_CODE = POS_STAG.JOB_CODE AND
JOB_MAP.TABLE_CODE = 'JOB' LEFT JOIN
XX_MAP LOC_MAP
ON LOC_MAP.SOURCE_CORE_HR_CODE = POS_STAG.LOCATION_CODE AND
LOC_MAP.BUSINESS_UNIT = POS_STAG.BUSINESS_UNIT_NAME AND
LOC_MAP.TABLE_CODE = 'LOC';

Multiple Join on the same table-Oracle

I tried the below query
SELECT Customer.*,
ElectrnicItem.Product1 AS ElectronicItem1,
ElectrnicItem.Product2 AS ElectronicItem2,
ElectrnicItem.Product3 AS ElectronicItem3,
ApparelItem.Product1 AS ApparelItem1,
ApparelItem.Product2 AS ApparelItem2,
ApparelItem.Product3 AS ApparelItem3
FROM Customer
LEFT JOIN Inventory AS ElectrnicItem
ON (Customer.CustomerID = ElectrnicItem.CustomerID)
LEFT JOIN Inventory AS ApparelItem
ON (Customer.CustomerID = ApparelItem.CustomerID)
but it always returns:
ORA-00918 column ambiguously defined
You're missing any predicate to identify rows in Inventory as either 'Electronic' or 'Apparel' for one thing. Not sure that's the fix though.
How about this?
SELECT a.customer_id, a.customer_name, b.product1 electronicitem1,
b.product2 electronicitem2, b.product3 electronicitem3,
c.product1 apparelitem1, c.product2 apparelitem2,
c.product3 apparelitem3
FROM customer a, inventory b, inventory c
WHERE a.customer_id = b.customer_id(+)
AND b.product_type(+) = 'Electronic'
AND a.customer_id = c.customer_id(+)
AND c.product_type(+) = 'Apparel';
I created tables Customer and Inventory, also inserted the values that you have provided. The following is the query :
select customer.*,ElectrnicItem.Product1 as ElectronicItem1,
ElectrnicItem.Product2 as ElectronicItem2,
ElectrnicItem.Product3 as ElectronicItem3,
ApparelItem.Product1 as ApparelItem1,
ApparelItem.Product2 as ApparelItem2,
ApparelItem.Product3 as ApparelItem3
from customer
left join inventory as ElectrnicItem on
(customer.CustomerID = ElectrnicItem.CustomerID )
left join inventory as ApparelItem
on (customer.CustomerID = ApparelItem.CustomerID )
It works fine and gives the following result:
1 David Miller mobile headphone trimmer mobile headphone trimmer
2 Johnson jeans tshirt NULL jeans tshirt NULL
3 Diggs NULL NULL NULL NULL NULL NULL
The expected output that you have mentioned will never be achieved. Because Customer table contains CustomerId and CustomerName, Customer.* will retrieve both CustomerId and CustomerName. So CustomerName column can not contain any NULL
values.
Ok, a bit late, but...
You donĀ“t use AS to alias a table in Oracle, only to alias a column. Try to drop all those AS from the tables aliases:
SELECT Customer.*,
ElectrnicItem.Product1 AS ElectronicItem1,
ElectrnicItem.Product2 AS ElectronicItem2,
ElectrnicItem.Product3 AS ElectronicItem3,
ApparelItem.Product1 AS ApparelItem1,
ApparelItem.Product2 AS ApparelItem2,
ApparelItem.Product3 AS ApparelItem3
FROM Customer
LEFT JOIN Inventory ElectrnicItem
ON (Customer.CustomerID = ElectrnicItem.CustomerID)
LEFT JOIN Inventory ApparelItem
ON (Customer.CustomerID = ApparelItem.CustomerID)