Conditional Join with replace and case - sql

I have two tables that I want to join.
The case is in table 1 the default value is 1 then in table 2 the default value is 0
Table 1 Table 2
-------- ---------
1 0
1232342 1232342
1241232 1231231
I want to join table 1 and table 2 with condition that if table 2 is 0 then it will be replaced to 1.
SELECT T1.ID
FROM TABLE1 T1, TABLE2 T2
WHERE T1.ID = REPLACE(CASE WHEN T2 = 0 THEN 1 ELSE T2.ID END, 'X', 'E')
with this statement it does not return the other id's that are not 0 or 1
expected output
Table 1
--------
1
1232342

Use a join with a CASE. replace() is for string values:
select t1.*
from table1 t1
join table2 t2 on t1.id = case when t2.id = 0 then 1 else t2.id end;

use case when and sub-query
select t1.* from table1 t1 join
(
select case when t2.id=0 then 1 else t2.id end as id from table2 t2
) as t3 on t1.id=t3.id

Try using case when :
SELECT *
FROM TABLE1 T1 inner join TABLE2 T2
on T1.ID = (CASE WHEN T2.ID =0 THEN 1 ELSE T2.ID END)

Switch to modern, explicit JOIN syntax. Skip the case expression, simply use AND/OR instead:
SELECT T1.ID
FROM TABLE1 T1
JOIN TABLE2 T2
ON T1.ID = T2.ID OR (T1.ID = 1 and T2.ID = 0)
Or use INTERSECT:
SELECT ID FROM TABLE1
INTERSECT
SELECT case when ID = 0 then 1 else id end from TABLE2

Related

How to create table with binary values based on existing some values in two other tables in Teradata SQL?

I have two tables in Teradata SQL like below:
Table1:
ID
10
11
12
Table2:
ID
10
13
14
15
Based on two tables above I need to create one table like below.
So:
col: tab1 --> If ID is in table 1 give them 1 and 0 otherwise.
col: tab2 --> If ID is in table 2 give them 1 and 0 otherwise.
Desired result:
ID
tab1
tab2
10
1
1
11
1
0
12
1
0
13
0
1
14
0
1
15
0
1
How can I do that in Teradata SQL ?
Teradata seems to support enough of ISO SQL-2003 natively, so no Teradata-specific SQL extensions or proprietary features is needed (i.e. the exact same query will work in MSSQL Server, Oracle, MariaDB, etc).
You'll want a UNION of table1 and table2's values and then JOINed back, which is straightforward:
WITH distinctIdValues AS (
SELECT id FROM table1
UNION
SELECT id FROM table2
)
SELECT
dv.id,
CASE WHEN t1.id IS NOT NULL THEN 1 ELSE 0 END AS tab1,
CASE WHEN t2.id IS NOT NULL THEN 1 ELSE 0 END AS tab2
FROM
distinctIdValues AS dv
LEFT OUTER JOIN table1 AS t1 ON dv.id = t1.id
LEFT OUTER JOIN table2 AS t2 ON dv.id = t2.id
You can then use this query either as a VIEW or materialize it into a new TABLE:
CREATE VIEW foobar AS /* same SQL as above */;
SELECT * FROM foobar;
Teradata's documentation is unclear about how/if a CTE can be used with an INSERT statement, so I'll use an inner-query instead:
CREATE TABLE foobar (
id int NOT NULL PRIMARY KEY,
tab1 byteint NOT NULL,
tab2 byteint NOT NULL
);
INSERT INTO foobar ( id, tab1, tab2 )
SELECT
dv.id,
CASE WHEN t1.id IS NOT NULL THEN 1 ELSE 0 END AS tab1,
CASE WHEN t2.id IS NOT NULL THEN 1 ELSE 0 END AS tab2
FROM
(
SELECT id FROM table1
UNION
SELECT id FROM table2
)
AS dv
LEFT OUTER JOIN table1 AS t1 ON dv.id = t1.id
LEFT OUTER JOIN table2 AS t2 ON dv.id = t2.id
ORDER BY
dv.id
;
Or just this:
Props to #dnoeth for reminding me that it can be reduced to this:
SELECT
COALESCE( t1.id, t2.id ) AS id,
CASE WHEN t1.id IS NULL THEN 0 ELSE 1 END AS tab1,
CASE WHEN t2.id IS NULL THEN 0 ELSE 1 END AS tab2
FROM
table1 AS t1
FULL OUTER JOIN table2 AS t2 ON t1.id = t2.id
ORDER BY
COALESCE( t1.id, t2.id )
You just need a Full Outer Join:
SELECT
Coalesce(t1.id, t2.id) AS id
,CASE WHEN t1.id IS NULL THEN 0 ELSE 1 END AS tab1
,CASE WHEN t2.id IS NULL THEN 0 ELSE 1 END AS tab2
FROM table1 AS t1
FULL JOIN table2 AS t2
ON t1.id = t1.id

Search record from one table in other table and receive info about this

In T1 I have a 50 ID'ss. I'm trying to find which ones are in T2. And add row name "test" next to ID with info about occurrence in T2. But when I put my code I receive only ID's which are included in T2. What I`m doing wrong?
SELECT DISTINCT t1.id, CASE WHEN t1.id IS NULL THEN 0 ELSE 1 END AS test
FROM t2
JOIN t1 ON t2.id = t1.id
You can use outer join:
SELECT DISTINCT t1.id, CASE WHEN t2.id IS NULL THEN 0 ELSE 1 END AS test
FROM t1 LEFT JOIN t2 ON t2.id = t1.id
Use exists:
select t1.*,
(case when exists (select 1 from t2 where t2.id = t1.id) then 1 else 0 end) as flag
from t1;
Note that select distinct is not needed. That construct just slows down queries, if it is not needed.
Use Left Join to get the unmatched rows as well.
select t1.id
, case when t2.id is null then 0 else 1 end as test
from t1
left outer join t2
on t1.id = t2.id

how to get data from a sub query and also know if sub query is empty or not?

I have three tables
T1 has columns:
Number, ID
T2 has columns:
Number, ID
T3 has columns:
Number, Name
I know an ID value: MYID.
I want to select every row from T3 where the Number is equal to any Number in T2 or T1 where with ID equal to the MYID. Also I want to know all the Numbers that are either in T1 or T2 that have a corresponding ID equal to MYID -- (the subquery below).
I have written this query:
SELECT * FROM T3 where T3.Number in
(SELECT T2.NUMBER FROM T2 where T2.ID=MYID
union
SELECT T1.NUMBER FROM T1 where T1.ID=MYID)
With this query some Numbers present in the subquery are not known if they are not present in T3. Now should I split into two queries or is there a way to get all that information in one query.
Thanks in advance.
I would suggest writing this as:
SELECT T3.*,
(CASE WHEN EXISTS (SELECT 1 FROM T2 WHERE T2.ID = MYID AND T2.NUMBER = T3.NUMBER)
THEN 1
WHEN EXISTS (SELECT 1 FROM T1 WHERE T1.ID = MYID AND T1.NUMBER = T1.NUMBER)
THEN 1
ELSE 0
END) as flag
FROM T3;
This is better than the UNION form because the subqueries can take advantage of indexes on T2 and T1.
In SQLServer try this: (im guessing that you know what MYID is, I don't)
WITH t
AS (SELECT
T2.number
FROM T2
WHERE T2.ID = MYID
UNION
SELECT
T1.number
FROM T1
WHERE T1.ID = MYID)
SELECT
*
,CASE
WHEN EXISTS (SELECT
*
FROM t
WHERE t.number = T3.number) THEN 1
ELSE 0
END AS ExistsInOtherSets
FROM T3
Considering that MYID is a hard coded value; something like this should do the trick ....
SELECT * FROM T3
where EXISTS (SELECT 1
FROM T2
where T2.NUMBER = T3.Number
AND T2.ID = MYID)
OR EXISTS (SELECT 1
FROM T1
where T1.NUMBER = T3.Number
AND T1.ID = MYID)

Execute different statements in one query on the condition

Say we have two Users with ID = 1 and ID = 2
I know the ID of the current User and I need to execute different select statements depending on the ID.
if ID = 1
select a from table1
else if ID = 2
select b from table2
else
select c from table3
Is there a way to put this logic into single SQL query?
You can use union with appropriate where conditions.
select a from table1 where id = 1
union all
select b from table2 where id = 2
union all
select c from table3 where id not in (1,2)
or if the tables can be joined
select
case when t1.id = 1 then t1.a
when t2.id = 2 then t2.b
else t3.c end
from table1 t1
join table2 t2 on t1.id = t2.id
join table3 t3 on t1.id = t3.id

Need help with Join Problem

I have 2 tables
Table 1
ID Status
1 D
2 F
3 D
Table 2
SID ID Approve
1 1 N
2 1 Y
3 1 Y
4 2 Y
5 3 Y
Result:- Should be
Table 1 (ID, Status)
3, D
2,F
Should not display 1 (As one of child rows have N in the Approve Column)
I need a query to joins 2 tables on ID and finds records that don not have N in their Approve column. Does anyone have any clue how to implement this?
I tried
SELECT * FROM Table1 AS t1
INNER JOIN Table2 AS t2
ON t2.id = t1.id
WHERE t2.Approve != 'N'
Doesn’t work
SELECT *
FROM Table1 t1
WHERE NOT EXISTS(SELECT * FROM Table2 t2 WHERE t2.ID = t1.ID AND t2.Approve = 'N')
More efficient and possibly easier to read is the following:
SELECT * FROM Table1 AS t1
LEFT JOIN Table2 AS t2
ON t2.id = t1.id
group by t1.id HAVING sum(t2.approve='Y') = count(t1.id)
Please Try
SELECT distinct t1.*
FROM Table1 AS t1
INNER JOIN Table2 AS tyes
ON tyes.id = t1.id
AND tyes.approve ='Y'
LEFT OUTER JOIN Table2 as tno
ON tno.id = t1.id
AND tno.approve ='N'
where tno.sid is null
It will select any line which is explicitely approved and never disapproved
Select * from table1 where id not in (select id from table2 where approve = 'N')
ID 1 is still returned since there is also a record in table 2 where approve = 'Y' for ID 1.
If you want to exclude any ID where approve is 'N' for any SID then you'll have to work with subqueries; roughly:
SELECT t1.ID,T1.Status FROM Table1 AS t1 INNER JOIN Table2 AS t2 ON t2.id = t1.id
where t1.id NOT IN (select id from Table2 where approve = 'N' and id = t1.id)
regards,
Stijn