Oracle SQL: Joining another table with one missing tuple - sql

I have the following two tables, one stores order information, one stores key|value information.
There is no CD = D for key COLOR_CD. I would like to join both tables to get all orders irregardless of the key|value pair not found in the MASS_DECODE table.
Can i get some help please :D
ORDER_INFORMATION
ORDER_NUMBER |COLOR_CD |
----------------|-----------|
1 |A |
2 |B |
3 |C |
4 |D |
MASS_DECODE
KEY |CD |VALUE |
------------|---------------|-----------|
COLOR_CD |A |Green |
COLOR_CD |B |Blue |
COLOR_CD |C |Red |
SIZE_CD |A |Large |
SIZE_CD |B |Medium |
SIZE_CD |C |Small |
SQL:
select order_number, cd, value
from order_information
left outer join mass_decode
on (color_cd = cd)
and key = 'COLOR_CD';
Outcome:
ORDER_NUMBER |CD |VALUE |
----------------|-----------|-----------|
1 |A |Green |
2 |B |Blue |
3 |C |Red |
Expected:
ORDER_NUMBER |CD |VALUE |
----------------|-----------|-----------|
1 |A |Green |
2 |B |Blue |
3 |C |Red |
4 |D |NULL |
EDIT: I am sorry i have presented incorrect information for my tables. Since been corrected.

select *
from order_information oi
left join mass_decode md
on (
oi.color_cd = md.cd
and oi.key = md.key
)
where oi.key = 'KEY_A';
SQLFiddle
upd:
According to your updates:
select *
from order_information oi
left join mass_decode md
on oi.color_cd = md.cd
where md.key = 'COLOR_CD' or md.key is null;
SQLFiddle

Your column names are ambiguous. You have two columns named the same in two tables, so which column does the key in your where clause refer to? I think in later versions of Oracle, this will actually give you an error. Try this:
select oi.order_number, oi.color_cd, md.value
from order_infomation oi
left outer join mass_decode md
on (oi.color_cd = md.cd)
where oi.key = 'KEY_A';
Edit:
Based on your response to #billy, it sounds like that wasn't working for you. You could also try putting the key predicate into the join clause:
select oi.order_number, oi.color_cd, md.value
from order_infomation oi
left outer join mass_decode md
on (oi.color_cd = md.cd) and oi.key = 'KEY_A';

This should do :
SELECT
order_number,
color_cd AS cd,
(
SELECT value FROM mass_decode m2 WHERE m2.key = o.key AND m2.cd = o.color_cd
) AS value
FROM order_information o
WHERE o.key = 'KEY_A'

Related

How to disregard a row in a returned MS Access query when all fields bar one are distinct

I'm trying to create a query on Access 2010 which only produces a single row per patient. There are a really small number of patients (each patient represented by
a unique nhs_number in the table n) who are listed as having 2 practices in the table pp and so two rows are generated for them. Is there a way I can arbitrarily select one of the practices and ignore the other?
This is the query:
SELECT DISTINCT
n.nhs_number,
IIF(ch.care_home_date>#2/1/1900#, "TRUE", "FALSE") AS care_home,
pp.practice
FROM (nhs_no_tbl AS n
LEFT JOIN patient_practice_tbl AS pp ON n.nhs_number = pp.nhs_number)
LEFT JOIN patient_care_home_tbl AS ch ON n.nhs_number = ch.nhs_number;
The tables the query is using contains data along these lines:
nhs_no_tbl:
|nhs_number|
| -------- |
|1 |
|2 |
|3 |
|4 |
patient_practice_tbl:
|nhs_number|practice|
| -------- | ------ |
|1 |GP_A |
|2 |GP_A |
|3 |GP_B |
|4 |GP_A |
|4 |GP_B |
patient_care_home_tbl:
|nhs_number|care_home_date|
| -------- | ------------ |
|1 |1/5/2000 |
|1 |1/10/2010 |
|4 |26/10/2017 |
At the end, I'd like the query to return the following:
|nhs_number|Care_home|practice|
| -------- | ------- | ------ |
|1 |TRUE |GP_A |
|2 |FALSE | |
|3 |FALSE | |
|4 |TRUE |GP_A [or GP_B] |
I've update the query with CTE,
;WITH cte1 AS ---select all results
(
SELECT DISTINCT nnt.nhs_number,
CASE WHEN pcht.care_home_date IS NULL
THEN 'FALSE'
ELSE 'TRUE'
END AS CareHome,
ppt.practice,
rank()OVER(PARTITION BY nnt.nhs_number ORDER BY ppt.practice) AS R
FROM #nhs_no_tbl nnt
LEFT JOIN #patient_practice_tbl ppt ON nnt.nhs_number = ppt.nhs_number
LEFT JOIN #patient_care_home_tbl pcht ON nnt.nhs_number = pcht.nhs_number
),
CTE2 AS ---choose who may have multiple pracices
(
SELECT nhs_number
FROM CTE1
WHERE R = 2
),
CTE3 AS --- combine GP_A and GP_B
(
SELECT t.nhs_number,STRING_AGG(val,',') AS Practices
FROM
(
SELECT DISTINCT val = cte1.practice, CTE1.nhs_number
FROM #nhs_no_tbl nnt
INNER JOIN CTE2 ON nnt.nhs_number = CTE2.nhs_number
INNER JOIN cte1 ON nnt.nhs_number = CTE1.nhs_number
) t
--RIGHT JOIN #nhs_no_tbl nnt ON t.nhs_number = nnt.nhs_number
GROUP BY t.nhs_number
)
SELECT cte1.nhs_number,cte1.carehome,cte1.practice, cte3.Practices
FROM CTE1
LEFT JOIN cte3 ON cte1.nhs_number = CTE3.nhs_number
The result would be
then next you could store the result into a temp table and update temp table where practices is not null.

Query to the get the Max value using Join in SQL Server

I have a table of Users:
|Username|UserType|
|John |A |
|Mary |A |
|Anna |B |
and UserPoints
|UserType|MinPoints|Level |
|A |100 |Bronze |
|A |200 |Silver |
|A |300 |Gold |
|B |500 |Bronze |
and Useraddress
|UserType|Address
|A |Address1
|B |Address2
I am looking for a query to get the max value of MinPoints column.
I want the result without using Group by clause.
I tried the below
Select UserType,UA.Address
,(Select max(MinPoints) from Users T1 WHERE T1.Usertype=U.Usertype)MinPoints from Users U
Left Join UserAddress UA on UA.UserType=U.UserType
Select UserType,UA.Address,MinPoints
from Users U
Left Join UserAddress UA on UA.UserType=U.UserType
Left Join (Select UserType,max(MinPoints) from Users T1 Group by UserType) x ON X.Usertype=U.Usertype
For the above queries I got the same result.
But what I want is which is query is better keeping in view the performance.
Please suggesst
This will return all user data for the user or users whose MinPoints are equal to the maximum value of MinPoints. With the sample data, JOIN will work, but you may need them to be LEFT JOINs.
SELECT
u.UserName,
ua.Address,
up.MinPoints AS MaxOfMinPoints
FROM
UserPoints AS up
JOIN
Users AS u
ON u.UserType = up.UserType
JOIN
UserAddress AS ua
ON ua.UserType = up.UserType
WHERE
up.MinPoints = (SELECT MAX(s.MinPoints) FROM UserPoints AS s)

Sum by groups between 2 tables

I, im trying to Sum by groups between 2 tables. Basically im trying to show only the Table 'Count' with each SUM() of Table 'MoneyMovements' group by 'Bank_code'. Is this possible?. I tryed with Left join (including the 'MoneyMovements'in 'Count'). but i dont understand how to separe the sum... Any suggestion?. Im using ACCESS 2007 in VB.NET
Table 'Count'
+----+--------------+
|Code|Bank |
+----+--------------+
|1 |MACRO |
+----+--------------+
|2 |Santender Rio |
+----+--------------+
|3 |Galicia |
+----+--------------+
Table 'MoneyMovements'
+-----+--------------+
|Money|Bank_code |
+-----+--------------+
|200 |1 |
+-----+--------------+
|300 |1 |
+-----+--------------+
|0 |2 |
+-----+--------------+
|500 |3 |
+-----+--------------+
|100 |3 |
+-----+--------------+
Response i Want:
+-----+--------------+
|Money|Bank |
+-----+--------------+
|500 |MACRO |
+-----+--------------+
|0 |Santender Rio |
+-----+--------------+
|600 |Galicia |
+-----+--------------+
You need join with group by like:
Select c.Code, sum(m.Money) as Money
From Count c
inner join MoneyMovements m on c.Code = m.Bank_code
group by c.Code
Use "Left join" to get all the "Count" rows and Nz() to display 0 when there are no transactions in an account:
Select c.Code, Nz(sum(m.Money),0) as Money
From Count c
LEFT JOIN MoneyMovements m on c.Code = m.Bank_code
group by c.Code
Access really didn't like the table name "Count" so I used Counts instead, this is what I did:
SELECT Counts.code, Nz(Sum(MoneyMovements.Money),0) AS SumOfMoney
FROM Counts LEFT JOIN MoneyMovements ON Counts.Code = MoneyMovements.bank_code
GROUP BY Counts.code;

Max value from joined table

I have two tables:
Operations (op_id,super,name,last)
Orders (or_id,number)
Operations:
+--------------------------------+
|op_id| super| name | last|
+--------------------------------+
|1 1 OperationXX 1 |
|2 1 OperationXY 2 |
|3 1 OperationXC 4 |
|4 1 OperationXZ 3 |
|5 2 OperationXX 1 |
|6 3 OperationXY 2 |
|7 4 OperationXC 1 |
|8 4 OperationXZ 2 |
+--------------------------------+
Orders:
+--------------+
|or_id | number|
+--------------+
|1 2UY |
|2 23X |
|3 xx2 |
|4 121 |
+--------------+
I need query to get table:
+-------------------------------------+
|or_id |number |max(last)| name |
|1 2UY 4 OperationXC|
|2 23X 1 OperationXX|
|3 xx2 2 OperationXY|
|4 121 2 OperationXZ|
+-------------------------------------+
use corelared subquery and join
select o.*,a.last,a.name from
(
select super,name,last from Operations from operations t
where last = (select max(last) from operations t2 where t2.super=t.super)
) a join orders o on t1.super =o.or_id
you can use row_number as well
with cte as
(
select * from
(
select * , row_number() over(partition by super order by last desc) rn
from operations
) tt where rn=1
) select o.*,cte.last,cte.name from Orders o join cte on o.or_id=cte.super
SELECT Orders.or_id, Orders.number, Operations.name, Operations.last AS max
FROM Orders
INNER JOIN Operations on Operations.super = Orders.or_id
GROUP BY Orders.or_id, Orders.number, Operations.name;
I don't have a way of testing this right now, but I think this is it.
Also, you didn't specify the foreign key, so the join might be wrong.

sql return categories ordered by blog post date

I've a Wordpress website with articles. A post can contain or more categories (table wp_terms). Now I want a query that returns a list of all term names, ORDERED BY the blogs article date. I have experimented with a SELECT in a SELECT query, but that doesn't work... How can I do it and return the categories ordered by the article date?
table wp_posts (as example):
|ID------|post_title------------------|post_date-|
|1 |Test title |2014-05-05|
|2 |Test title 2 |2014-04-01|
|3 |Last test title |2014-02-02|
|4 |Another blog item |2014-01-06|
table wp_terms:
|term_id|name---------|
|1 |computers |
|2 |home |
|3 |work |
table wp_term_relationships
|object_id|term_taxonomy_id|term_order|
|1 |2 | 0 |
|1 |1 | 0 |
|2 |3 | 0 |
table wp_term_taxonomy
|term_taxonomy_id | term_id |
|1 |1 |
|2 |2 |
|3 |3 |
|4 |4 |
This is my current query, but this doesn't work right...
SELECT t.*, p.* FROM wp_terms AS t
JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id
JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tr.term_taxonomy_id
LEFT JOIN ( SELECT `ID`, `post_title`, max(`post_date`) as `date` FROM wp_posts
GROUP BY `ID` ) as p on p.`ID`= tr.`object_id` GROUP BY t.`term_id` ORDER BY p.`date` desc
Still not sure what you are trying to achieve. But this is your query which runs without errors
SELECT t.*, p.*
FROM wp_terms AS t JOIN wp_terms_taxonomy AS tt
ON tt.term_id = t.term_id
JOIN wp_terms_relationship AS tr
ON tr.term_taxonomy_id
= tr.term_taxonomy_id LEFT JOIN
( SELECT ID, post_title, max(post_date) as date
FROM wp_posts
GROUP BY ID , post_title) as p on p.ID= tr.object_id
GROUP BY t.term_id,t.name,p.id,p.post_title,p.date
ORDER BY p.date desc
fiddle