How to exclude records based on second table (using JOIN) - sql

I think this is simple, but not so today...
I have two tables The first has a column with data from the second.
T1 has Column1 value = "Created"
T2 has Column1 Value = "Created" and Column2 Value = "OPEN"
So the idea is to return every row from table 1 where column 2 of table 2 = "OPEN"
This si the current SELECT
SELECT tblCustIncidents.IncidentID, tblCustIncidents.EntryDateTime, tblCustIncidents.Title, tblCustIncidents.StatusType, tblCustIncidents.Summary, tblMaintStatusTypes.StatusDescr
FROM tblCustIncidents LEFT JOIN
tblMaintStatusTypes
ON tblCustIncidents.StatusType = tblMaintStatusTypes.StatusType;
I thought I could just use WHERE but I am not clear on the location of the WHERE or even if it will work... I've been looking more than a little while. I'll keep looking and hope someone can point me tot he right method/answer/post etc. Thanks.
In the screenshot of the returned data the last column is in both tables. The second table has a column indictaing if the item is open or closed. SO I would want all records in the snippet NOT to appear... I have tried this Select statement...
SELECT tblCustIncidents.IncidentID, tblCustIncidents.EntryDateTime, tblCustIncidents.Title, tblCustIncidents.StatusType, tblCustIncidents.Summary, tblMaintStatusTypes.StatusDescr
FROM tblCustIncidents LEFT JOIN tblMaintStatusTypes ON tblCustIncidents.StatusType = tblMaintStatusTypes.StatusType
WHERE tblMaintStatusTypes.OpenOrClosedType = 'Open';
OK I figured out access is picky... so I have tried this...
SELECT tblCustIncidents.IncidentID,
tblCustIncidents.EntryDateTime,
tblCustIncidents.Title,
tblCustIncidents.StatusType,
tblCustIncidents.Summary,
tblMaintStatusTypes.StatusDescr
FROM tblCustIncidents
inner join (SELECT tblCustIncidents.IncidentID,
tblCustIncidents.EntryDateTime,
tblCustIncidents.Title,
tblCustIncidents.StatusType,
tblCustIncidents.Summary,
tblMaintStatusTypes.StatusDescr
FROM tblCustIncidents)
ON (tblCustIncidents.StatusType = tblMaintStatusTypes.StatusType AND tblMaintStatusTypes.OpenOrClosedType = 'Open');

SELECT t1.*
FROM table1 t1
JOIN table2 t2
ON t1.Column1=t2.Column1
WHERE t2.column2='OPEN'

Based on your query you just need to add clause to the join and than change join from left to inner, otherwise you will still get all rows from table 1.
SELECT tblCustIncidents.IncidentID
,tblCustIncidents.EntryDateTime
,tblCustIncidents.Title
,tblCustIncidents.StatusType
,tblCustIncidents.Summary
,tblMaintStatusTypes.StatusDescr
FROM tblCustIncidents
INNER JOIN tblMaintStatusTypes
ON tblCustIncidents.StatusType = tblMaintStatusTypes.StatusType
WHERE tblMaintStatusTypes.Column2 = 'OPEN'

Related

When a column has a certain string, i want to replace it with a string from my left join

I was wondering if anyone could help. I want my main table to keep the meter records in my main table and when i get 'Others' i want these to be replaced by the left join tables.
The issue is when im doing my case when, my result is coming back as null?
The thing is with the data im left joining too it has a lot of other data that i have to filter and a join on with which might make this question a bit more complicated. First of all i just want to make sure my case when is working correctly before i do anymore testing.
Thanks!
WITH CTE_MAIN AS (
SELECT DISTINCT
EX.Meter,
CASE WHEN (EX.Metermodel) = 'Other'
THEN OJ.Metermodel
ELSE EX.Metermodel
END AS MeterModelRemoved
FROM `MAINTABLE` AS EX
LEFT JOIN `LEFTTABLE` AS OJ ON EX.METER=OJ.METER)
SELECT * #Test
FROM CTE_MAIN
WHERE Meter = 'G4A50027940101'
Main Table
METER
Metermodel
G4A50027940101
Other
000807612
Other
L0117797762M
Other
009X091
U6
5046314S
G4
Left join table
METER
Metermodel
G4A50027940101
U6
000807612
G4
L0117797762M
G4
009X091
U6
5046314S
LPG
Result: MeterModelRemoved = null
Few more options:
In case if both tables have exact same structure (as it is in your question) - consider below approach
select if(t1.Metermodel = 'Other', t2, t1).*
from MainTable t1
left join LeftTable t2
using(METER)
in case if structure of second table is different and potentially has more columns that you don't need in output - use classic approach
select METER, if(t1.Metermodel = 'Other', t2.Metermodel, t1.Metermodel) as Metermodel
from MainTable t1
left join LeftTable t2
using(METER)
if applied to sample data in y our question - both have same output
The only time you will have null value is if there is no matching record in the second table. If you want to handle this, you can use the value from the main table as a fallback, which can be done using COALESCE.
CASE WHEN (EX.Metermodel) = 'Other'
THEN COALESCE(OJ.Metermodel, EX.Metermodel)
ELSE EX.Metermodel
END AS MeterModelRemoved

SQL - How to put a condition for which table is selected without left join

I have a flag in a table which value ( 1 for US, or 2 for Global) indicates if the data will be in Table A or Table B.
A solution that works is to left join both tables; however this slows down significantly the scripts (from less than a second to over 15 seconds).
Is there any other clever way to do this? an equivalent of
join TableA only if TableCore.CountryFlag = "US"
join TableB only if TableCore.CountryFlag = "global"
Thanks a lot for the help.
You can try using this approach:
-- US data
SELECT
YourColumns
FROM
TableCore
INNER JOIN TableA AS T ON TableCore.JoinColumn = T.JoinColumn
WHERE
TableCore.CountryFlag = 'US'
UNION ALL
-- Non-US Data
SELECT
YourColumns -- These columns must match in number and datatype with previous SELECT
FROM
TableCore
INNER JOIN TableB AS T ON TableCore.JoinColumn = T.JoinColumn
WHERE
TableCore.CountryFlag = 'global'
However, if the result is still slow, you might want to check if the TableCore table has a index on CountryFlag and JoinColumn, and TableA and TableB an index on JoinColumn.
The basic structure is:
select . . ., coalesce(a.?, b.?) as ?
from tablecore c left join
tablea a
on c.? = a.? and c.countryflag = 'US' left join
tableb b
on c.? b.? and c.counryflag = 'global';
This version of the query can take advantage of indexes on tablea(?) and tableb(?).
If you have a complex query, this portion is probably not responsible for the performance problem.

Query using CASE, WHEN, THEN in postgresql not working

I have three tables, tbl_doctors_details, tbl_time and tbl_token.
I have to select the details from tbl_time or tbl_token. That is if for particular doctor in hospital have t_type is time then select from tbl_time else select from tbl_token.
For example, for doctor_id is 100 and hospital_id 1, the t_type is time. So for this user, details should select from tbl_time table.
Below is the sample structure and data of three tables:
How can I use CASE condition in query here?
I tried:
SELECT *
FROM
( SELECT * CASE WHEN t_type= 'time' FROM dbname.tbl_doctors_details t1 THEN
dbname.tbl_time t2
ELSE
dbname.tbl_token t2
WHERE t1.hospital_id=t2.hospital_id AND t1.doctor_id=t2.doctor_id);
I know the query is not working, but how can I make the query working?
You need to join both tables using two LEFT JOINs and then COALESCE to find the matching data:
SELECT t1.*,
colaesce(t_time.hospid, t_token.hospid),
colaesce(t_time.start, t_token.start)
FROM dbname.tbl_doctors_details t1
LEFT JOIN dbname.tbl_time t_time
ON t1.doctor_id=t_time.doctor_id
AND t1.t_type= 'time'
LEFT JOIN dbname.tbl_token t_token
ON t1.doctor_id=t_token.doctor_id
AND t1.t_type= 'token';
Use CASE WHEN in your SELECT and LEFT JOIN both tables. In both LEFT JOIN use the condition of t_type to join on the tables. In your SELECT you can now check whether table t1 or t2 was joined and select the preferred column. Here's a sample (the selected column is just a sample to illustrate):
SELECT CASE WHEN t1.id IS NULL THEN t2.id ELSE t1.id END AS joined_id
FROM tbl_doctors_details as tbl_base
LEFT JOIN tbl_time t1 ON t1.t_type = 'time' AND t1.doc_id = tbl_base.doc_id
LEFT JOIN tbl_token t2 ON t2.t_type = 'token' AND t2.doc_id = tbl_base.doc_id
Serious smell of doing homework for someone here.. Meh
SELECT
doctors.*
, CASE
WHEN doctors.type = 'time' THEN time.start
ELSE token.start
END AS start
FROM
doctors
LEFT OUTER JOIN time
ON time.doc_id = doctors.doc_id
AND time.hospital_id = doctors.hospital_id
AND doctors.t_type = 'time'
LEFT OUTER JOIN token
ON token.doc_id = doctors.doc_id
AND token.hospital_id = doctors.hospital_id
AND doctors.t_type = 'token'

Oracle left outer join, only want the null values

I'm working on a problem with two tables. Charge and ChargeHistory. I want to display a selection of columns from both tables where either the matching row in ChargeHistory has a different value and/or date from Charge or if there is no matching entry in ChargeHistory at all.
I'm using a left outer join declared using the ansi standard and while it does show the rows correctly where there is a difference, it isn't showing the null entries.
I've read that there can sometimes be issues if you are using the WHERE clause as well as the ON clause. However when I try and put all the conditons in the ON clause the query takes too long > 15 minutes (so long I have just cancelled the runs).
To make things worse both tables use a three part compound key.
Does anyone have any ideas as to why the null values are being left out?
SELECT values...
FROM bcharge charge
LEFT OUTER JOIN chgHist history
ON charge.key1 = history.key1 AND charge.key2 = history.key2 AND charge.key3 = history.key3 AND charge.chargeType = history.chargeType
WHERE charge.chargeType = '2'
AND (charge.value <> history.value OR charge.date <> history.date)
ORDER BY key1, key2, key
You probably want to explicitly select the null values:
SELECT values...
FROM bcharge charge
LEFT OUTER JOIN chgHist history
ON charge.key1 = history.key1 AND charge.key2 = history.key2 AND charge.key3 = history.key3 AND charge.chargeType = history.chargeType
WHERE charge.chargeType = '2'
AND ((charge.value <> history.value or history.value is null) OR (charge.date <> history.date or history.date is null))
ORDER BY key1, key2, key
You can explicitly look for a match in the where. I would recommend looking at one of the keys used for the join:
SELECT . . .
FROM bcharge charge LEFT OUTER JOIN
chgHist history
ON charge.key1 = history.key1 AND charge.key2 = history.key2 AND
charge.key3 = history.key3 AND charge.chargeType = history.chargeType
WHERE charge.chargeType = '2' AND
(charge.value <> history.value OR charge.date <> history.date OR history.key1 is null)
ORDER BY key1, key2, key;
The expressions charge.value <> history.value change the left outer join to an inner join because NULL results will be filtered out.
A WHERE clause filters the data returned by a join. Therefore when your inner table has null data for a particular column, the corresponding rows get filtered out based on your specified condition. That is why you should move that logic to the ON clause instead.
For the performance issues, you could consider adding indexes on the columns used for joining and filtering.
Have a look at this site, it will be very helpful for you, visual illustration of all the join statements with code samples
blog.codinghorror.com
Quoted of the relevant info in the above link:
SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
Sample output:
id name id name
-- ---- -- ----
1 Pirate 2 Pirate
2 Monkey null null
3 Ninja 4 Ninja
4 Spaghetti null null
Left outer join
produces a complete set of records from Table A, with the matching records (where available) in Table B. If there is no match, the right side will contain null
For any field from an outer joined table used in the where clause you must also permit an IS NULL option for that same field, otherwise you negate the effect of the outer join and the result is the same as if you had used an inner join.
SELECT
*
FROM bcharge charge
LEFT OUTER JOIN chgHist history
ON charge.key1 = history.key1
AND charge.key2 = history.key2
AND charge.key3 = history.key3
AND charge.chargeType = history.chargeType
WHERE charge.chargeType = '2'
AND (
(charge.value <> history.value OR history.value IS NULL)
OR
(charge.date <> history.date OR history.date IS NULL)
)
ORDER BY
key1, key2, key3
Edit: Appears that this is the same query structure used by Rene above, so treat this one as in support of that please.

A SQL case statement or two

I have a SELECT statement that pulls these two different product strips. When I delete one of them from the website and rerun my statement I still have two rows, the first column has the ARMCODE twice (two results) and the second column has the description for the first but then no description for the second (because it has been deleted).
Problem is it's still showing two results in SQL studio with the ARMCODE.
If there is a a.CODE_,a.strips from intake it needs to show, if there is an A.ARMCODE and B.DESCRIPTION it needs to show. If there is only A.ARMCODE and B.DESCRIPTION and the other has been deleted why is it still showing two results with a.CODE_ being the second result and an empty a.strips.
select a.ARMCODE,
b.DESCRIPTION_
from ARE.AAS.REORDER a
left outer join ARE.AAS.PTDME b on a.PTCODE=b.CODE_
where a.ARMCODE = 'ADSMANZS03'
and b.MEDICAREID ='A4253'
union all
select a.CODE_,a.strips
from event.dbo.intake a
where a.CODE_ = 'ADSMANZS03'
I started on a new statement using case and am now using some nested joins:
select case when b.ARMCODE is null then a.strips
end
from (select *
from ev.dbo.intake a
where a.CODE_ = 'ADSMANZS03') a
left outer join(select a.ARMCODE,
b.DESCRIPTION_
from ARE.AAS.REORDER a
left outer join ARE.AAS.PTDME b on a.PTCODE=b.CODE_
where a.ARMCODE = 'ADSMANZS03'
and b.MEDICAREID ='A4253') b on a.CODE_=b.ARMCODE
I'm not getting any rows or columns and it's returning (no column name) and inside NULL
Hope that is not too confusing. Thanks in advance.
IMAGE 1 Strips and description, two different products, same patient
IMAGE 2 When i delete strips, still showing two results with empty description, should not show a second result.
IMAGE 3 case statement
Just an fyi so this question can be closed. I used coalesce to determine what i needed.
select
coalesce(b.DESCRIPTION_,a.strips)
from(
select
*
from ev.dbo.intake a
where a.CODE_ = 'ADSMANZS03'
)a
left outer join(
select
a.ARMCODE,
b.DESCRIPTION_
from ARE.AAS.REORDER a
left outer join ARE.AAS.PTDME b on a.PTCODE=b.CODE_
where a.ARMCODE = 'ADSMANZS03'
and b.MEDICAREID ='A4253'
)b on a.CODE_=b.ARMCODE
COALESCE (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms190349.aspx