input table 1 (5 6 7) (Five Six Seven) and table 2 (5 6 7 ). Both in brackets are columns with values.,I want to get the five for the 5 in table2 - sql

table 1
col1
col2
5
five
6
six
8
eight
table 2
5|6|5
6|5
8|8|5
Expected output
|five|six|five|
|six|five|
|eight|eight|five|

That "link" you're talking about is called a join.
As you put it, that would be as follows:
Sample data (you already have that and don't type it):
SQL> with
2 table_1 (col1, col2) as
3 (select 5, 'five' from dual union all
4 select 6, 'six' from dual union all
5 select 8, 'eight' from dual
6 ),
7 table_2 (col1) as
8 (select 5 from dual union all
9 select 6 from dual union all
10 select 8 from dual
11 )
12 --
Query begins here:
13 select b.col1
14 from table_1 a join table_2 b on a.col1 = b.col1
15 where a.col2 = '&par_col2';
Enter value for par_col2: five
COL1
----------
5
SQL> /
Enter value for par_col2: eight
COL1
----------
8
SQL>
Depending on a tool you use, where clause might use a bind variable instead of a substitution one (I used in SQL*Plus), i.e.
where a.col2 = :par_col2
On the other hand, what do you need table_2 for? Everything you need is contained in table_1, so query would then be just
<snip>
13 select a.col1
14 from table_1 a
15 where a.col2 = '&par_col2';
Enter value for par_col2: six
COL1
----------
6
SQL>

Related

How to create a unique pairwise list of a column value based on table entry and its referenced entry in oracle

Im trying to extract the following information from the oracle table below: A list of all the unique pairwise Status combinations for entries and their referenced entries. Entries with no referenced entry will be ignored. For example, for the entry 10 I expect the output to be (1,3) because its status is 1 and the status of the referenced entry 7 is 3. If the list doesn't already have this combination, it should be added to the list. Can anyone guide me in the right direction? I'm totally clueless as to how to even google what I want to achieve.
EDIT: The first column is the ID of the entry, the second column is the status of the entry, and the third column is the ID of another entry in the same table that is referenced.
Looks like a self join:
Sample data:
SQL> with test (id, status, ref_id) as
2 (select 1, 0, null from dual union all
3 select 2, 1, 3 from dual union all
4 select 3, 3, null from dual union all
5 select 4, 6, 6 from dual union all
6 select 5, 0, 1 from dual union all
7 select 6, 4, null from dual union all
8 select 7, 3, null from dual union all
9 select 8, 5, 9 from dual union all
10 select 9, 2, null from dual union all
11 select 10, 1, 7 from dual
12 )
Query:
13 select a.id, a.status, b.status
14 from test a join test b on b.id = a.ref_id
15 where a.ref_id is not null
16 order by a.id;
ID STATUS STATUS
---------- ---------- ----------
2 1 3
4 6 4
5 0 0
8 5 2
10 1 3
SQL>
If you want to get distinct pairs (but still know IDs involved), you could use listagg (it'll work as long as resulting string doesn't exceed 4000 characters; if it does, use xmlagg instead):
13 select listagg(a.id, ', ') within group (order by a.id) id,
14 a.status, b.status
15 from test a join test b on b.id = a.ref_id
16 where a.ref_id is not null
17 group by a.status, b.status
18 order by id;
ID STATUS STATUS
-------------------- ---------- ----------
2, 10 1 3
4 6 4
5 0 0
8 5 2
SQL>
If you don't care about IDs, then
13 select distinct a.status, b.status
14 from test a join test b on b.id = a.ref_id
15 where a.ref_id is not null
16 order by a.status, b.status;
STATUS STATUS
---------- ----------
0 0
1 3
5 2
6 4
SQL>

How can I select a data from another column from rows that have been selected?

I tried my best to figure and google this out, but couldn't really find a solid answer to it.
The problem I'm facing is that
Table 1:
ID Value 1
1 a
2 b
3 c
Table 2:
ID Value 2
1 4a
3 5b
4 6c
and I'd basically have to select the value from Table 1 that doesn't exist on Table 2 (Thus, 'b')
I can select and identify the ID that I want by using minus function between the tables, but can't seem to figure out a way to call a query to instead call the data.
Use the MINUS as a subquery (i.e. an inline view) (lines #14 - 16):
Sample data:
SQL> with
2 table1(id, value1) as
3 (select 1, 'a' from dual union all
4 select 2, 'b' from dual union all
5 select 3, 'c' from dual
6 ),
7 table2 (id, value2) as
8 (select 1, '4a' from dual union all
9 select 3, '5b' from dual union all
10 select 4, '6c' from dual
11 )
Query begins here:
12 select a.*
13 from table1 a
14 where a.id in (select t1.id from table1 t1
15 minus
16 select t2.id from table2 t2
17 );
ID VALUE1
---------- ----------
2 b
SQL>
Alternatively, use not exists:
<snip>
12 select a.*
13 from table1 a
14 where not exists (select null
15 from table2 b
16 where b.id = a.id
17 );
ID VALUE1
---------- ----------
2 b
SQL>

How to cross join with out using a table?

Recently, I am trying to create a table. I have a column that contains 'a', 'b', 'c' and would like to cross join it with 1,2,3 in to the table below.
However, I don't have a table that contains values 1,2,3 and need to do it without creating a table.
Can I achieve this without creating any table? Thanks a lot!
Col1
a
b
c
Col1 Col2
a 1
b 1
c 1
a 2
b 2
c 2
a 3
b 3
c 3
Use a CTE instead:
SQL> with
2 a (col) as
3 (select 'a' from dual union all
4 select 'b' from dual union all
5 select 'c' from dual
6 ),
7 b (col) as
8 (select 1 from dual union all
9 select 2 from dual union all
10 select 3 from dual
11 )
12 select a.col, b.col
13 from a cross join b;
C COL
- ----------
a 1
a 2
a 3
b 1
b 2
b 3
c 1
c 2
c 3
9 rows selected.
SQL>
You can use:
SELECT *
FROM table1
CROSS JOIN (SELECT LEVEL AS col2 FROM DUAL CONNECT BY LEVEL <= 3);
or
WITH data (col1, col2) AS (
SELECT col1, 1 FROM table1
UNION ALL
SELECT col1, col2 + 1 FROM data WHERE col2 < 3
)
SELECT * FROM data;
Which, given your sample data:
CREATE TABLE table1 (col1) AS
SELECT 'a' FROM DUAL UNION ALL
SELECT 'b' FROM DUAL UNION ALL
SELECT 'c' FROM DUAL;
Both output:
COL1
COL2
a
1
b
1
c
1
a
2
b
2
c
2
a
3
b
3
c
3
db<>fiddle here
You can create "tables" within your query in many different ways, several of which have been illustrated in other answers already.
For your request I like an XML solution as shown below:
create table table1 (col1 varchar2(1));
insert into table1(col1) values('a');
insert into table1(col1) values('b');
insert into table1(col1) values('c');
commit;
select t1.col1, xmlcast(column_value as number) as col2
from table1 t1 cross join xmltable('1 to 3')
;
COL1 COL2
---- ----
a 1
a 2
a 3
b 1
b 2
b 3
c 1
c 2
c 3

SQL interview questions

Table-1
Col1 col2
11 A
26 B
31 C
43 D
Table-2
Col1 col2
16 E
46 F
39 G
42 H
And need output is
Col1 col2 Col1 col2
11 A 16 E
26 B 46 F
31 C 39 G
43 D 42 H
Here's one option:
SQL> with
2 -- sample data
3 a (col1, col2) as
4 (select 11, 'A' from dual union all
5 select 26, 'B' from dual union all
6 select 31, 'C' from dual union all
7 select 43, 'D' from dual
8 ),
9 b (col1, col2) as
10 (select 16, 'E' from dual union all
11 select 46, 'F' from dual union all
12 select 39, 'G' from dual union all
13 select 42, 'H' from dual
14 ),
15 -- find something to join rows on - for example, row number. Your example shows that
16 -- values are sorted by COL2
17 a2 as
18 (select col1, col2, row_number() over (order by col2) rn from a),
19 b2 as
20 (select col1, col2, row_number() over (order by col2) rn from b)
21 -- join a2 and b2 on RN
22 select a2.col1, a2.col2, b2.col1, b2.col2
23 from a2 join b2 on a2.rn = b2.rn
24 order by a2.col1;
COL1 COL2 COL1 COL2
----- ---- ----- ----
11 A 16 E
26 B 46 F
31 C 39 G
43 D 42 H
SQL>
select t1.col1, t1.col2, t2.col1, t2.col2 from table1 as t1
left join table2 as t2 on 1=1
Try this
select * from table1 t1 join table2 t2 on ascii(t1.col2)+4 = ascii(t2.col2);
Note: this only works with the specific input provided, but why not? It just goes to show that providing minimal input and expected output is not sufficient. You have to explain what rules the input should follow and what rules the processing should follow.
Littlefoot answers a different question than I do, but even he silently makes some assumptions. For example, he decided not to show any output if there are unmatched rows on one side or the other.
The correct real-world answer to this interview question would be to list the questions one would have to ask before being able to supply an appropriate answer.

Join two tables with a column with multiple entries for the other table

I have the following problem.
I want to join two tables.
The first table has entries like the following:
T1
PK Info
1 one
2 two
3 three
The second table is build like this:
T2
PK FKT1
1 1,3
2 1,2,3
3 2
My Result should show the following
PK2 FKT1 InfoT1
1 1,3 One,Three
2 1,2,3 One,two,Three
3 2 Two
I just cant get an idea how to solve this.
Is this possible only using sql selects or is a function needed?
kind regards
It's not that difficult, but - as you were told, you'd rather NOT do that.
SQL> with
2 t1 (pk, info) as
3 (select 1, 'one' from dual union
4 select 2, 'two' from dual union
5 select 3, 'three' from dual
6 ),
7 t2 (pk, fkt1) as
8 (select 1, '1,3' from dual union
9 select 2, '1,2,3' from dual union
10 select 3, '2' from dual
11 ),
12 t2rows as
13 (select pk, regexp_substr(fkt1, '[^,]+', 1, column_value) fkt1, column_value rn
14 from t2,
15 table(cast(multiset(select level from dual
16 connect by level <= regexp_count(fkt1, ',') + 1
17 ) as sys.odcinumberlist))
18 )
19 select t2r.pk,
20 listagg(t2r.fkt1, ',') within group (order by t2r.rn) fkt1,
21 listagg(t1.info, ',') within group (order by t2r.rn) infot1
22 from t2rows t2r join t1 on t2r.fkt1 = t1.pk
23 group by t2r.pk
24 order by t2r.pk;
PK FKT1 INFOT1
---------- -------------------- --------------------
1 1,3 one,three
2 1,2,3 one,two,three
3 2 two
SQL>