sql query join multiple tables on a case when column - sql

i have sql like this:
select case when.....end as colA, table2.col3
from table1
join table2 on table2.colB = colA
in the case when statement, there are some other tables columns, is this doable? I have got error saying that colA is not valid.

Column aliases are not understood in the where or on clauses.
You can do this with a subquery, assuming the case only involves columns from table1:
select case when.....end as colA, t2.col3
from (select table1.*, (case when.....end) as colA
from table1
) t1 join
table2 t2
on t2.colB = t1.colA;
Otherwise, you could put the case statement in the on clause:
select case when.....end as colA, t2.col3
from (select table1.*, (case when.....end) as colA
from table1
) t1 join
table2 t2
on t2.colB = ( case when.....end );

Related

SQL CASE WHEN in table

I have two tables: table1 and table2 both with one column for ID. I want to create a column in table1 that displays 'Y' if ID in table1 is in table2 and 'N' if it is not.
Currently, I am using:
Select id, case when id in (table2) then 'Y' else 'N' end as in_table2
from table1
However, since both tables are very big, the query is taking forever. Is there a more efficient way of doing this?
Thanks
Use exists:
Select t1.id,
(case when exists (select 1 from table2 t2 where t2.id = t1.id)
then 'Y' else 'N'
end) as in_table2
from table1 t1;
This should be much quicker and efficient than using exists/subqueries:
SELECT t1.id ,
CASE WHEN t2.id IS NULL
THEN 'N'
ELSE 'Y'
END AS in_table2
FROM table1 t1
LEFT JOIN TABLE2 t2 ON t1.id = t2.id;
By left joining you maintain visibility of the records on table2, and if the ID is null, you know it exists on table1 but not on table2, so you can safely use a case statement to show Y or N based on t2.id.

Join two tables to get common data based on a column

I have two tables:
Table1 with columns colA, colB, colC
Table2 with columns colX, colY, colZ
I'm trying to get all rows from Table1 which have colC values that match Table2 on colZ.
I tried the following:
select Table1.colA,Table1.colB,Table1.colC
from Table1 inner join Table2 on Table1.colC = Table2.colZ
This does not seem to work as the result of the query had 20 times the number of rows present in Table1.
Any help is sincerely appreciated.
You can use EXISTS like this.
select Table1.colA,Table1.colB,Table1.colC from Table1
WHERE EXISTS (SELECT 1 FROM Table2 WHERE Table1.colC = Table2.colZ)
Three options:
Use INNER JOIN with DISTINCT
SELECT DISTINCT Table1.colA,
Table1.colB,
Table1.colC
FROM Table1
INNER JOIN Table2 ON Table1.colC = Table2.colZ
Use EXISTS
SELECT Table1.colA,
Table1.colB,
Table1.colC
FROM Table1 WHERE EXISTS (SELECT 1 FROM Table2 WHERE ColZ = ColC)
Use IN
SELECT Table1.colA,
Table1.colB,
Table1.colC
FROM Table1
WHERE ColC IN (SELECT ColZ FROM Table2)
Use DISTINCT in your query:
SELECT DISTINCT
Table1.colA,Table1.colB,Table1.colC
FROM Table1
INNER JOIN Table2
ON Table1.colC = Table2.colZ

Troubleshoot - Ambiguous column name xyz

I run the following query and I get the ambiguous error. Why is it happening ?
select *
from dbo.tableA as table1, dbo.tableZ as table2
where (columnB = dbo.tableZ.columnB)
Ambiguous column name columnB
tableA also has a column named columnB.
Both tables have a columnB but the first part of your condition doesn't specify from which table to use columnB.
Change it to this:
select *
from dbo.tableA as table1, dbo.tableZ as table2
where (table1.columnB = table2.columnB)
You need to use the alias for the field names. It's a good rule to reference your fields using the alias when creating joins so that others can read the SQL easier...
e.g.
SELECT t1.ColA ,
t1.ColB ,
t2.ColA
FROM Table1 AS t1
INNER JOIN Table2 AS t2 ON t1.Id = t2.FId
instead of...
SELECT ColA ,
ColB ,
ColA
FROM Table1 AS t1
INNER JOIN Table2 AS t2 ON t1.Id = t2.FId
I know the second SQL query would not parse, but it's just an example.

SQL: add string to field when other value changes

I have 2 columns (ColA, ColB) both are datatype Nvarchar.
I need col B to be unique for the values in ColA
Some rows have 2 different values in ColA with the same value (non-unique) in ColB.
I want to write a query to display the ColB values along with the letter "D" (as duplicate) at the end, where the value in ColA is changing to something else.
As far as I can understand, you want to mark the rows where the ColB value needs to be changed.
If so try something like this
SELECT t1.COLA,
t1.COLB + 'D'
FROM TABLE1 t1
INNER JOIN TABLE1 t2
ON t1.COLB = t2.COLB
AND t1.COLA != t2.COLA
This will only show the "double" rows. If you want to show all the rows, just add a UNION to the end:
SELECT t1.COLA,
t1.COLB + 'D'
FROM TABLE1 t1
INNER JOIN TABLE1 t2
ON t1.COLB = t2.COLB
AND t1.COLA != t2.COLA
UNION
SELECT *
FROM TABLE1
WHERE COLA NOT IN (SELECT t1.COLA
FROM TABLE1 t1
INNER JOIN TABLE1 t2
ON t1.COLB = t2.COLB
AND t1.COLA != t2.COLA)
See the full example at SQL Fiddle.

How to add a row to the result of a SQL query with INNER JOIN?

In times past, when I need to add a row to the result of a SQL statement, I write a statement like this:
SELECT colA, colB FROM my_table
UNION
SELECT 'foo' AS colA, 'bar' as colB;
However, suppose I've written the following SQL:
SELECT t1.colA, t1.colB, t2.colC FROM my_table t1 INNER JOIN my_other_table t2
How can I add my extra row to my_table when it is INNER JOINed to another table like this?
Update: Wow, I just goofed. It's almost going-home time. I forgot my where clause!
SELECT t1.colA, t1.colB, t2.colC
FROM my_table t1
INNER JOIN my_other_table t2
ON t1.colB = t2.colC
SELECT
(t1.colA, t1.colB FROM my_table
UNION
SELECT 'foo' AS colA, 'bar' as colB) as t1
INNER JOIN
my_other_table t2 ON . . .
SELECT t1.colA, t1.colB, t2.colC FROM my_table t1 INNER JOIN my_other_table t2
UNION
SELECT 'foo' as colA, 'bar' as colB, 'baz' as colC
Just replace mytable in your second query with (SELECT ...), the whole first query (in parenthesis):
SELECT t1.colA, t1.colB, t2.colC
FROM
( SELECT colA, colB
FROM my_table
UNION
SELECT 'foo' AS colA, 'bar' as colB
) AS t1
INNER JOIN my_other_table t2
ON t1.colB = t2.colC
;