I have two table say T1 and T2 and one column C is common to both. I need an SQL query in which if C is null in T1 it will select from other table.
I tried writing SELECT statement in THEN clause but not running. Don't know is there any IF ELSE clause in SQL.
Select C, case when c = null Then Select c from T2
from T1
Even better, most RDBMSs support COALESCE, which lets you check multiple values and return the first non-null value.
SELECT COALESCE(T1.C, T2.C) AS C
FROM T1
LEFT OUTER JOIN T2 ON T1.[Primary Key] = T2.[Primary Key]
Is this in TransactSQL?
I like the first answer, however you could also do it this way...
select case t1.C
when null then t2.C
else t1.C
end as [testC]
from t1
inner join t2
on t1.PKID = t2.PKID
What you seem to need is a union
select c from t1
where c is not null
union
select c from t2
where c is not null
Now you get all the columns C from T1and T2 in one result set but only if not null.
Well of course if this has simplified your problem too much you need to work with a join
select coalesce(t1.c,t2.c) as c
from t1
left join t2 on (t2.id = t1.foreign_id)
This assumed that T2.ID is the primary key and related to T1 with T1.FOREIGN_ID
It is important that you do a left join because otherwise you only get T1 rows when the row also exists in T2.
Related
Initially, I have a query like below, doing a join on 1=1. (It's simply doing a cross join, which selects all rows from the first table and all rows from the second table and shows as a cartesian product, i.e. with all possibilities.)
SELECT * FROM Table1 t1
JOIN Table2 t2 ON 1=1
Problem: Optimize this query in such a way, it will show only the records for a particular ID and if we don't have an ID or have a NULL in the ID then it will show the result same as previously(1=1). So I wrote the script below.
Declare #T2id as int;
Set #T2id = 123;
SELECT * FROM Table1 t1
JOIN Table2 t2 ON
-- left side of join on statement
CASE
WHEN #T2id Is NULL
THEN 1
ELSE
t2.Id
END
=
-- right side of join on statement
CASE
WHEN #T2id Is NULL
THEN 1
ELSE
#T2id
END
Can anyone confirm, is it good or we can have a better approach than this?
I think your way of presenting a cross-join is something I haven't seen before.
My view is it's simpler to read and understand if you just:
SELECT *
FROM Table1 t1, Table2 t2
As for the question, assuming SQL Server (you didn't tag the RDBMS, but I guess from your variable declaration) you might consider:
IF ISNULL(#T2id,1) = 1
SELECT *
FROM Table1 t1, Table2 t2;
ELSE
SELECT *
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.id = t2.id
WHERE t2.id = #T2id;
I want to fetch all records with all columns of a table, Records which are not in the other 2 tables. Please help.
I have tried below query, it is working fine for comparing one column. But I want to compare 5 columns.
select * from A
WHERE NOT EXISTS
(select * from B b where b.id=a.id) AND
NOT EXISTS
(select * from C c where c.id=a.id)
A general solution might look like:
SELECT t1.*
FROM table1 t1
WHERE NOT EXISTS (SELECT 1 FROM table2 t2 WHERE t2.id = t1.t2_id) AND
NOT EXISTS (SELECT 1 FROM table3 t3 WHERE t3.id = t1.t3_id);
This assumes that you want to target table1 for records, ensuring that no matches can found in table2 and table3.
I prefer this approach:
SELECT t1.*
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t1.id = t2.t1_id
LEFT JOIN table3 AS t3
ON t1.id = t3.t1_id
WHERE t2.id IS NULL
AND t3.id IS NULL;
While this might be a bit less intuitive than using sub queries I think odds of making mistakes with aliases are less likely as in the example below, which happens more often than you might expect:
SELECT *
FROM table1
WHERE NOT EXISTS (SELECT 1 FROM table2 WHERE id = id) AND
NOT EXISTS (SELECT 1 FROM table3 WHERE id = id);
To your question about checks on 5 columns, that can still be done using either of these methods by adding conditions either in the left joins or in the where clause of each sub query.
I have the below query
Select sum (ABC) as ecr from table1
Where a<>'y' or b is null and c<>'g'
Union all
Select sum(bcd) as ech from table2
Note: I am getting results under one column but I want to be displayed under two columns
Please try this.
SELECT sum (A.ABC) as ecr,SUM(B.bcd) as ech
FROM table1 AS A
LEFT JOIN table2 AS B
ON B.Id = A.Id
Where A.a<>'y' or A.b is null and A.c<>'g'
I think you just need a cross join
Select sum(ABC) as ecr,
sum(bcd) as ech
from table1 t1
cross join table2
Where t1.a <> 'y'
or t1.b is null
and t1.c <> 'g'
In MS Access, you use , for CROSS JOIN:
select t1.ecr, t2.ech
from (select sum(ABC) as ecr
from table1
where a <> 'y' or b is null and c <> 'g'
) t1,
(select sum(bcd) as ech
from table2
) t2;
In any other database, you would use CROSS JOIN.
I have a table t1. It has columns [id] and [id2].
Select count(*) from t1 where id=1;
returns 31,189 records
Select count(*) from t1 where id=2;
returns 31,173 records
I want to know the records where id2 is in id=1 but not in id=2.
So, I use the following:
Select * from t1 a left join t1 b on a.id2=b.id2
Where a.id=2 And b.id=1
And b.id2 Is Null;
It returns zero records.
Using an inner join to see how many records have id2 in common, I do...
Select * from t1 a inner join t1 b on a.id2=b.id2
Where a.id=2 And b.id=1;
And that returns 31,060. So where are the extra records in my first query that don't match?
I am sure I must be missing something obvious.
Sample Data
id id2
1 101
1 102
1 103
2 101
2 102
My expected results is to find the record with '103' in it. 'id2' not shared.
Thanks for any help.
Jeff
You are attempting to do what is generally called an exclude join. This involves doing a LEFT JOIN between two tables, then using a WHERE clause to only select rows where the right table is null, i.e. there was no record to join. In this way, you select everything from the left table except what exists in the right table.
With this data, it would look something like this:
SELECT
t1.id,
t1.id2
FROM test_table t1
LEFT JOIN
(SELECT
id,
id2
FROM test_table
WHERE id = 2) t2
ON t2.id2 = t1.id2
WHERE t1.id = 1
AND t2.id IS NULL --This is what makes the exclude join happen
And here is a SQLFiddle demonstrating this in MySQL 5.7 with the sample data you provided.
I think maybe Access changes the left join to an inner join when you add a where clause to filter rows (I know SQL Server does this), but if you do the filtering in derived tables it should work:
select
a.*
from
(select * from t1 where id = 1) a
left join
(select * from t1 where id = 2) b
on a.id2 = b.id2
where b.id2 is null
Is it possible to write a sql query where you know you have to use the left outer join..but cannot or are not allowed to use the "outer join" Key Word
I have two table sand want to get rows with null vaues from the left table ...this is pretty simple ...but am not supposed to use the key word....outer join....I need to right the logic for outer join myself
SELECT Field1
FROM table1
WHERE id NOT IN (SELECT id FROM table2)
SELECT Field1
FROM table1
WHERE NOT EXISTS (SELECT * FROM table2 where table2.id = table1.id)
This is something people do but it is deprecated and it does not currently work correctly (it sometimes will return a cross join instead of a left join) so it should NOT be used. I'm telling this only so you avoid using this solution.
SELECT Field1
FROM table1, table2 where table1.id *= table2.id
;WITH t1(c,d) AS
(
SELECT 1,'A' UNION ALL
SELECT 2,'B'
),t2(c,e) AS
(
SELECT 1,'C' UNION ALL
SELECT 1,'D' UNION ALL
SELECT 3,'E'
)
SELECT t1.c, t1.d, t2.c, t2.e
FROM t1, t2
WHERE t1.c = t2.c
UNION ALL
SELECT t1.c, t1.d, NULL, NULL
FROM t1
WHERE c NOT IN (SELECT c
FROM t2
WHERE c IS NOT NULL)
Returns
c d c e
----------- ---- ----------- ----
1 A 1 C
1 A 1 D
2 B NULL NULL
(Equivalent to)
SELECT t1.c, t1.d, t2.c, t2.e
FROM t1
LEFT JOIN t2
ON t1.c = t2.c
For SQL Server, you can just use LEFT JOIN - the OUTER is optional, just like INTO in an INSERT statement.
This is the same for all OUTER JOINs.
For an INNER JOIN you can just specify JOIN with no qualifiers and it is interpreted as an INNER JOIN.
This will give you all the rows in table A that don't have a matching row in table B:
SELECT *
FROM A
WHERE NOT EXISTS (
SELECT 1
FROM B
WHERE A.id = B.id
);
Returns all the matching rows from both tables:
SELECT a.*,b.* FROM table_a a, table_b b
WHERE a.key_field = b.key_field
Potential drawback is non-matches will be skipped.