I have a SQL query in which I want to use INNER JOIN with the UPPER keyword.
=> CASE A with INNER JOIN: I am doing INNER JOIN with the other table. Notice I have not written the complete query so you won't find INNER JOIN keyword below.
=> CASE B without INNER JOIN: I am not doing INNER JOIN with the other table. Notice I have not written the complete query.
1st query:
Case A with INNER JOIN: UPPER(hello_world.column_name1) AS COLUMN_NAME1,
CASE B without INNER JOIN: UPPER(column_name1) AS COLUMN_NAME1,
2nd query:
CASE A with INNER JOIN: UPPER(CASE WHEN hello_world.COLUMN_NAME2 IS NULL THEN 'Open' ELSE hello_world.COLUMN_NAME2 END) AS COLUMN_NAME2,
CASE B without INNER JOIN: UPPER(CASE WHEN COLUMN_NAME2 IS NULL THEN 'Open' ELSE COLUMN_NAME2 END) AS COLUMN_NAME2,
Problem Statement:
I am wondering if its the right way to use INNER JOIN with the UPPER keyword (CASE A in both queries).
If it yields the results you expect, then yes. INNER JOIN is the act of joining two tables, that is, based on a criteria, records from table1 will be matched by records from table2 as long as they meet the criteria and such matches will yield records of table3, i.e. the result.
Your criteria needs to be boolean, that is, it can be true and it can be false. In the formula of your criteria you may use the UPPER function, like
...
FROM A
JOIN B
ON UPPER(A.X) = UPPER(B.Y)
...
Yet, your UPPER(hello_world.column_name1) AS COLUMN_NAME1 strongly suggests that you ponder about the SELECT clause of a query, which, based on your description has a join. The use of UPPER is useful wherever it makes sense and it is syntactically correct.
Related
Is there any difference in these two queries in terms of processing and data obtained:
SELECT * from Table A Inner JOIN Table B ON A.id = B.id
LEFT JOIN Table B ON A.id = C.id AND (C.status IS NULL OR C.status <>3)
WHERE A.status = 1 and B.status = 1
OR
SELECT * from Table A Inner JOIN Table B ON A.id = B.id
LEFT JOIN Table B ON A.id = C.id
WHERE A.status = 1 and B.status = 1 AND (C.status IS NULL OR C.status <>3)
After a deep dive into left joins and different clauses, Here is what I have came up:
1) When to use where and on clauses in case of joins:
In case of inner joins, it really does not matter where you give your conditions in where clause or on clause. Giving conditions in where clause will be used to filtering the data and giving the conditions in on clause will be to used to join the table. For readability purpose it is good to provide the filtering conditions in where clause only just to make sure you convince your intent through your query. But here is the catch, the query plan will change depending on where you pass your conditions and can heavily affect you.
In case of outer joins(left, right, full) passing conditions blindly in where and on clause can give you incorrect data.
2) When Left Join(or any outer join) can start behaving like inner joins
Be careful when you specify filtering conditions for null values in where clause. Suppose you have two tables: Users and orders and you want irrespective of whether they have placed order or not, so we chose left join. Further we have condition to filter condition like noOfOrders > 3, but since it was a left join values where null in products table. All null values will be filtered out, since null<0, hence left join will behave like an inner join.
My LEFT OUTER JOIN clause on a table (not the first table) on itself (self-join too) is not returning null values, which skews my SELECT statements. The query is written (table names inconsequential):
Select
SUM(CASE WHEN table2.date =‘day’ and table4.columnX =‘5’ then table3.value1 END),
SUM(CASE WHEN table2.date=’day’ and table4.columnX IS NULL then table3.value2 END)
FROM table1
INNER JOIN table2 on ...
INNER JOIN table3 on ...
LEFT OUTER JOIN table4 on table4.columnX=’5’
In which the first SUM(CASE WHEN) statement uses on one value in table4.columnX - when it is equal to '5' - and the second SUM(CASE WHEN) statement uses all other values - whenever it is not equal to '5'.
As it stands, the query is only returning results where table4.columnX='5', and not where table4.columnX is equal to everything else. As such, it appears the LEFT OUTER JOIN is not returning all null values for table4.columnX<>'5'. I think this may be because the join is written incorrectly. As a note, there are no fields in table4 that can be joined to fields in other tables, so it has to be a self-join of some sort (I believe). Help is appreciated - thank you!
What a LEFT OUTER JOIN will do is take all the rows from the "left table" and conditionally join rows from the "right table". If for a specific row in the "left table", there is no matching row in the "right table", then your "right data values" for the joined row will be NULL.
Your join condition is strange, though, since it doesn't reference another table. If that's really what you want, then you should change it to a CROSS JOIN:
Old: LEFT OUTER JOIN table4 on table4.columnX=’5’
New: CROSS JOIN table4 on table4.columnX=’5’
This will join all rows in table4 where columnX = 5 to each row in your preceding query above. Not sure if that's what you're looking for...
The inner query here returns values that only appear in one of the tables. The outer query is supposed to return a count of those. Instead, it returns the entire table, not just the NULL values.
select count(*) from tblicd
where exists
(
select i.icd_id
from tblicd i left outer join icd_jxn on icd_jxn.icd_id=i.icd_id
where icd_jxn.icd_id is null
)
The inner query
select i.icd_id
from tblicd i left outer join icd_jxn on icd_jxn.icd_id=i.icd_id
where icd_jxn.icd_id is null
works and does what I want. I'd like (using a sub query method like this) to use the outer query to just return the number of rows that the inner query returns.
You need to join the two (outer and inner) tblicd tables in the subquery:
and i.icd_id = tblicd.icd_id
(or whatever the id of the tblicd table is)
The query you posted doesn't make any sense. However, from your description, it sounds like you've got two tables and you're trying to find any IDs that don't exist in both tables. If that's correct, you should try something like this:
select count(*) as cnt
from table1 t1
full outer join
table2 t2
on t1.id = t2.id
where t1.id is null
or t2.id is null
This may not work in the database you're using, but since you didn't tell us that, we can't tailor the solution to fit your dialect of SQL.
Based on the revised question, you could simplify this a number of ways:
select count(*)
from tblicd
where not exists (select i.icd_id
from icd_jxn
where icd_jxn.icd_id = tblicd)
select count(tblicd.icd_id)
from tblicd
left join
icd_jxn
on tblicd.icd_id = icd_jxn.icd_id
where icd_jxn.icd_id is null
select count(tblicd.icd_id)
from tblicd
where icd_id not in (select icd_id
from icd_jxn)
Basically, there's no reason to select from tblicd twice.
Can you tell me if inner join and equi-join are the same or not ?
An 'inner join' is not the same as an 'equi-join' in general terms.
'equi-join' means joining tables using the equality operator or equivalent. I would still call an outer join an 'equi-join' if it only uses equality (others may disagree).
'inner join' is opposed to 'outer join' and determines how to join two sets when there is no matching value.
Simply put: an equi-join is a possible type of inner-joins
For a more in-depth explanation:
An inner-join is a join that returns only rows from joined tables where a certain condition is met. This condition may be of equality, which means we would have an equi-join; if the condition is not that of equality - which may be a non-equality, greater than, lesser than, between, etc. - we have a nonequi-join, called more precisely theta-join.
If we do not want such conditions to be necessarily met, we can have
outer joins (all rows from all tables returned), left join (all rows
from left table returned, only matching for right table), right join
(all rows from right table returned, only matching for left table).
The answer is NO.
An equi-join is used to match two columns from two tables using explicit operator =:
Example:
select *
from table T1, table2 T2
where T1.column_name1 = T2.column_name2
An inner join is used to get the cross product between two tables, combining all records from both tables. To get the right result you can use a equi-join or one natural join (column names between tables must be the same)
Using equi-join (explicit and implicit)
select *
from table T1 INNER JOIN table2 T2
on T1.column_name = T2.column_name
select *
from table T1, table2 T2
where T1.column_name = T2.column_name
Or Using natural join
select *
from table T1 NATURAL JOIN table2 T2
The answer is No,here is the short and simple for readers.
Inner join can have equality (=) and other operators (like <,>,<>) in the join condition.
Equi join only have equality (=) operator in the join condition.
Equi join can be an Inner join,Left Outer join, Right Outer join
If there has to made out a difference then ,I think here it is .I tested it with DB2.
In 'equi join'.you have to select the comparing column of the table being joined , in inner join it is not compulsory you do that . Example :-
Select k.id,k.name FROM customer k
inner join dealer on(
k.id =dealer.id
)
here the resulted rows are only two columns rows
id name
But I think in equi join you have to select the columns of other table too
Select k.id,k.name,d.id FROM customer k,dealer d
where
k.id =d.id
and this will result in rows with three columns , there is no way you cannot have the unwanted compared column of dealer here(even if you don't want it) , the rows will look like
id(from customer) name(from Customer) id(from dealer)
May be this is not true for your question.But it might be one of the major difference.
The answer is YES, But as a resultset. So here is an example.
Consider three tables:
orders(ord_no, purch_amt, ord_date, customer_id, salesman_id)
customer(customer_id,cust_name, city, grade, salesman_id)
salesman(salesman_id, name, city, commission)
Now if I have a query like this:
Find the details of an order.
Using INNER JOIN:
SELECT * FROM orders a INNER JOIN customer b ON a.customer_id=b.customer_id
INNER JOIN salesman c ON a.salesman_id=c.salesman_id;
Using EQUI JOIN:
SELECT * FROM orders a, customer b,salesman c where
a.customer_id=b.customer_id and a.salesman_id=c.salesman_id;
Execute both queries. You will get the same output.
Coming to your question There is no difference in output of equijoin and inner join. But there might be a difference in inner executions of both the types.
I have a join on two tables defined as a left outer join so that all records are returned from the left hand table even if they don't have a record in the right hand table. However I also need to include a where clause on a field from the right-hand table, but.... I still want a row from the left-hand table to be returned for each record in the left-hand table even if the condition in the where clause isn't met. Is there a way of doing this?
Yes, put the condition (called a predicate) in the join conditions
Select [stuff]
From TableA a
Left Join TableB b
On b.Pk = a.Pk
-- [Put your condition here, like this]
And b.Column = somevalue
The reason this works is because the query processor applies conditions in a where clause after all joins are completed, and the final result set has been constructed. So, at that point, a column from the a table on the outer side of a join that has null in a a column you have established a predicate on will be excluded.
Predicates in a join clause are applied before the two result sets are "joined". At this point all the rows on both sides of the join are still there, so the predicate is effective.
You just need to put the predicate into the JOIN condition. Putting it into the WHERE clause would effectively convert your query to an inner join.
For Example:
...
From a
Left Join b on a.id = b.id and b.condition = 'x'
You can use
WHERE (right_table.column=value OR right_table.column IS NULL)
This will return all rows from table 1 and table 2, but only where table 1 does not have a corresponding row in table 2 or the corresponding row in table 2 matches your criteria.
SELECT x.fieldA, y.fieldB
FROM x
LEFT OUTER JOIN (select fieldb, fieldc from Y where condition = some_condition)
ON x.fieldc = y.fieldc
select *
from table1 t1
left outer join table2 t2 on t1.id = t2.id
where t1.some_field = nvl(t2.some_field, t1.some_field)
UPD: errr... no. this way:
select *
from table1 t1
left outer join table2 t2 on t1.id = t2.id
where some_required_value = nvl(t2.some_field, some_required_value)
nvl is an Oracle syntax which replaces first argument with second in case it is null (which is common for outer joins). You can use ifnull or coalesce for other databases.
Thus, you compare t2.some_field with your search criteria if it has met join predicate, but if it has not, then you just return row from table1, because some_required_value compared to itself will always be true (unless it is null, however - null = null yields null, neither true not false.