SQL query from extracted column - sql

I have the following oracle sql query:
SELECT DISTINCT A, B, C, D
FROM my_table
WHERE (B IN (SELECT ID_X FROM table2))
This is fine because B is in table2.
Now I would like to query for column D which is not in table2 but can be mapped from my_table via D.
Table "my_table":
A
B
C
D
abc
def
ghi
jmk
Table "table2":
B
value
def
2
How can I first extract the value of column B if I only have the value of column D:
jmk -> def
And then use that value to extract my data from table2:
def -> 2

Use an inner join:
SELECT DISTINCT t1.*, t2.value
FROM my_table t1
INNER JOIN table2 t2
ON t2.ID_X = t1.B;

With your sample data:
WITH
tbl AS ( Select 'abc' "A", 'def' "B", 'ghi' "C", 'jmk' "D" From Dual ),
tbl_1 AS ( Select 'def' "B", 2 "VALUE" From Dual )
try this:
SELECT t.A, t.B, t.C, t.D, t1.VALUE "VALUE_OF_B"
FROM tbl t
LEFT JOIN tbl_1 t1 ON(t1.B = t.B)
WHERE t.D = 'jmk'
R e s u l t :
A B C D VALUE_OF_B
--- --- --- --- ----------
abc def ghi jmk 2
If there is no match of column B in tbl_1 you will get the row where VALUE_OF_B is null. If you put INNER instead of LEFT JOIN then, without the match, no rows will be selected. It's up to you to decide what kind of join to use...

Related

Oracle SQL Update column with data from another table using three conditional statements

Scenario:
I have two separate tables (table 1 and table 2)
I want to update a column from table one with the value of a column from table 2
Case 1:
I need columns b,c and d in table 1 to match b,c and d in table 2 before the update occurs
Case 2:
Column b in table 1 has a true value but Column b in table two references a look up (example in table 1 column b may have a value of blue but in table 2 column b has the value 14567 which is the id in a lookup table that references blue)
How would you accomplish getting this update completed?
create table ta as
select 1 ID,'Alex' Name , 27 age from dual
union
select 2 ID,'Bob' Name , 32 age from dual;
create table tb as
select 1 ID,'Alex' Name , 29 age from dual
union
select 5 ID,'Dick' Name , 24 age from dual;
update ta a
set a.age = (select b.age from tb b where a.id=b.id and b.name=a.name)
where exists ( select 1 from tb where a.id=tb.id and a.name = tb.name);
Assuming table lookup has columns b (corresponding to t2.b) and col_x (corresponding to t1.b), you could do something like this, using the merge statement:
merge into t1
using (
select t2.a, l.col_x, t2.c, t2.d
from t2 join lookup l on t2.b = l.b
) s
on (t1.b = s.col_x and t1.c = t2.c and t1.d = t2.d)
when matched then update
set t1.a = s.a
;

Left join but maintain values where NULL may result in Microsoft SQL

I have two tables:
Table A:
id names
1 a
2 b
3 c
and Table B:
id names
1 x
2 y
I'd like to perform a left join of Table B on Table A that results in the following table:
id names
1 x
2 y
3 c
How can I do this in Microsoft SQL?
You could use COALESCE:
SELECT a.id, COALESCE(b.name, a.name) AS name
FROM tab1 a
LEFT JOIN tab2 b
ON a.id = b.id
I think you just want coalesce():
select a.id, coalesce(b.name, a.name) as name
from a left join
b
on a.id = b.id;

Select statement to select item in table 1 that does not exist in table 2

I am writing a simple select statement to compare two different tables.
table 1 table 2
a a
b b
c c
H d
e
f
I need to select any item in table 1 that does not exist in table 2.
You have a few options, one of which is
select table1.col from table1 where
not exists (select col from table2 where table2.col = table1.col)
SELECT table_1.name
FROM table_1
LEFT JOIN table_2 ON table_1.name = table_2.name
WHERE table_2.name IS NULL
Subquery should do it:
Select * from table1
where Id not in
(select distinct col from table2)
Since it looks like there is only one column.
Try this.
select * from table a -- select all of the things in a
minus
select * from table b -- remove from it the things in b

Help required with a complex self join sql query

myTable is having composite key formed of columns A and B (total columns A, B, C, D, E).
I want to exclude/ignore records where value of D (say order number) is same and E (say decision) is Y in one but N or Null in other. (means all the twin-records with same order number (equal D value) which were ordered first (so E=Y) and then again cancelled (so E=N) should be ignored)
So I pulled out A,B for all records where D is same but E is Y in one and N in other
SELECT *
FROM myTable A, myTable B
WHERE
(A.D=B.D)
AND
((A.E ='Y' AND (B.E ='N' OR B.E IS NULL)) OR (B.E='Y' AND (A.E='N' OR A.E IS NULL)))
Now my final output should be all records from myTable but not the records found above.
I wrote a join query but its not working as it should. Basically issue is how to compare two composite keys ??
Sample Data:
A B C D E
=========================
1 A xyz ONE Y
2 B pqr TWO Y
3 C lmn ONE N
4 D abc THREE Y
5 E ijk FOUR Y
=========================
Thus, my output should be records 2,4 and 5. As 1 and 3 will be ignored. Because 1.D = 3.D and 1.E is Y but 3.E is N.
Thanks,
Nik
I want to exclude records where value of D is "XYZ".
Why not simply query like this directly?
select *
from myTable
where D <> 'XYZ'
To exclude rows from Temp, you could:
select *
from myTable
where not exists
(
select *
from temp
where myTable.A = temp.A
and myTable.B = temp.B
)
Or with an exclusive left join:
select *
from myTable
left join
temp
on myTable.A = temp.A
and myTable.B = temp.B
where temp.A is null
If I've correctly understood you, what you need is this:
select x.*
from mytable x left outer join
( select mt1.a, mt1.b
from mytable mt1 inner join
mytable mt2 on mt1.d = mt2.d
where ((mt1.E ='Y' AND (mt2.E ='N' OR mt2.E IS NULL)) OR (mt2.E='Y' AND (mt1.E='N' OR mt1.E IS NULL)))
) y on x.a = y.a and x.b = y.b
where y.a is NULL
You need something like
select A.*
from myTable A
WHERE (SELECT COUNT(*) FROM myTable B WHERE B.D = A.D AND (B.E IS NULL OR B.E = 'N')) = 0

Problem combining result of two different queries into one

I have two tables (TableA and TableB).
create table TableA
(A int null)
create table TableB
(B int null)
insert into TableA
(A) values (1)
insert into TableB
(B) values (2)
I cant join them together but still I would like to show the result from them as one row.
Now I can make select like this:
select
(select A from tableA) as A
, B from TableB
Result:
A B
1 2
But if I now delete from tableB:
delete tableB
Now when I run the same query as before:
select
(select A from tableA) as A
, B from TableB
I see this:
A B
But I was expecting seeing value from tableA
like this:
Expected Result:
A B
1
Why is this happening and how can I still see the value from TableA although selectB is returning 0 rows?
I am using MS SQL Server 2005.
Use a LEFT JOIN (although it's more of a cross join in your case).
If your db supports it:
SELECT a.a, b.b
FROM a
CROSS JOIN b
If not, do something like:
SELECT a.a, b.b
FROM a
LEFT JOIN b ON ( 1=1 )
However, once you have more rows in a or b, this will return the cartesian product:
1 1
1 2
2 1
2 2
This will actually give you what you're looking for, but if you only have one row per table:
select
(select A from tableA) as A
, (select B from TableB) as B
give this a try:
DECLARE #TableA table (A int null)
DECLARE #TableB table (B int null)
insert into #TableA (A) values (1)
insert into #TableB (B) values (2)
--this assumes that you don't have a Numbers table, and generates one on the fly with up to 500 rows, you can increase or decrease as necessary, or just join in your Numbers table instead
;WITH Digits AS
(
SELECT 0 AS nbr
UNION SELECT 1 UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
)
, AllNumbers AS
(
SELECT u3.nbr * 100 + u2.nbr * 10 + u1.nbr + 1 AS Number
FROM Digits u1, Digits u2, Digits u3
WHERE u3.nbr * 100 + u2.nbr * 10 + u1.nbr + 1 <= 500
)
, AllRowsA AS
(
SELECT
A, ROW_NUMBER() OVER (ORDER BY A) AS RowNumber
FROM #TableA
)
, AllRowsB AS
(
SELECT
B, ROW_NUMBER() OVER (ORDER BY B) AS RowNumber
FROM #TableB
)
SELECT
a.A,b.B
FROM AllNumbers n
LEFT OUTER JOIN AllRowsA a on n.Number=a.RowNumber
LEFT OUTER JOIN AllRowsB b on n.Number=b.RowNumber
WHERE a.A IS NOT NULL OR b.B IS NOT NULL
OUTPUT:
A B
----------- -----------
1 2
(1 row(s) affected)
if you DELETE #TableB, the output is:
A B
----------- -----------
1 NULL
(1 row(s) affected)
try this:
select a, (select b from b) from a
union
select b, (select a from a) from b
should retrieve you all the existing data.
you can filter it more by surrounding it with another select