Display data from multiple tables in Oracle in one line - sql

I have got 3 tables as follows:
table_teams (id_team, name, city)
table_matches (id_match, date_of_match, city)
table_game (id, id_team (FK), id_match (FK), goals) -- this one is a junction table between the first two
The same match is introduced into table_game as two separate records, one for each team with its number of goals, but having the same id_match,
INSERT INTO table_game(id_team, id_match, goals) VALUES('GER', 1234, 7);
INSERT INTO table_game(id_team, id_match, goals) VALUES('BRA', 1234, 1);
and as a single record into table_matches,
INSERT INTO table_matches(id_match, date_of_match, city)
VALUES (1234, '8-JUL-2014', 'Belo Horizonte');
Now, I would like to create a view that selects data from these tables and displays it as follows:
Date | Team1 | Goals1 | Goals2 | Team2 | City
The best I managed to do so far is display each record on separate lines in the table.
SELECT tm.date_of_match, tt.name, tg.goals, tm.city
FROM table_matches tm, table_teams tt, table_game tg
WHERE tm.id_match = tg.id_match AND tt.id_team = tg.id_team;
But I have no idea how to display data as stated above. All my tries resulted in a big mess.
Will appreciate some help. Thank you.

Using JOIN syntax
-- Test data
WITH table_game(ID, id_team, id_match, goals) AS (
SELECT 10, 'USA', 100, 5 FROM dual UNION ALL -- error (3 records for same match)
SELECT 11, 'RUS', 100, 4 FROM dual UNION ALL -- error (3 records for same match)
SELECT 12, 'BRA', 100, 3 FROM dual UNION ALL -- error (3 records for same match)
SELECT 20, 'ARG', 1234, 7 FROM dual UNION ALL
SELECT 21, 'BRA', 1234, 1 FROM dual UNION ALL
SELECT 30, 'ENG', 4321, 6 FROM dual UNION ALL
SELECT 31, 'FRA', 4321, 2 FROM dual
)
,table_matches(id_match, date_of_match, city) AS (
SELECT 1234, DATE '2014-07-08', 'Belo Horizonte' FROM dual UNION ALL
SELECT 4321, DATE '2014-08-09', 'Sao Paulo' FROM dual UNION ALL
SELECT 100, DATE '2014-09-10', 'Brasilia' FROM dual)
,table_teams(id_team, NAME, city) AS (
SELECT 'ARG', 'Argentina', 'Buenos Aires' FROM dual UNION ALL
SELECT 'BRA', 'Brazil', 'Sao Paulo' FROM dual UNION ALL
SELECT 'ENG', 'England', 'London' FROM dual UNION ALL
SELECT 'FRA', 'France', 'Paris' FROM dual UNION ALL
SELECT 'RUS', 'Russia', 'Moscow' FROM dual UNION ALL
SELECT 'USA', 'United States', 'New York' FROM dual)
-- End Test data
,match_teams AS (
SELECT id_match, MAX(id_team) team1, MIN(id_team) team2
FROM table_game
GROUP BY id_match
HAVING COUNT(*) = 2 -- any valid match should have only 2 teams, otherwise ignored
)
SELECT M.date_of_match, t1.NAME team1, g1.goals goals1, t2.NAME team2, g2.goals goals2, M.city city_match
FROM table_matches M
JOIN match_teams mt ON mt.id_match = M.id_match
JOIN table_game g1 ON g1.id_match = M.id_match AND g1.id_team = mt.team1
JOIN table_game g2 ON g2.id_match = M.id_match AND g2.id_team = mt.team2
JOIN table_teams t1 ON t1.id_team = mt.team1
JOIN table_teams t2 ON t2.id_team = mt.team2
/
Joins on WHERE clause
-- Test data
WITH table_game(ID, id_team, id_match, goals) AS (
SELECT 10, 'USA', 100, 5 FROM dual UNION ALL -- error (3 records for same match)
SELECT 11, 'RUS', 100, 4 FROM dual UNION ALL -- error (3 records for same match)
SELECT 12, 'BRA', 100, 3 FROM dual UNION ALL -- error (3 records for same match)
SELECT 20, 'ARG', 1234, 7 FROM dual UNION ALL
SELECT 21, 'BRA', 1234, 1 FROM dual UNION ALL
SELECT 30, 'ENG', 4321, 6 FROM dual UNION ALL
SELECT 31, 'FRA', 4321, 2 FROM dual
)
,table_matches(id_match, date_of_match, city) AS (
SELECT 1234, DATE '2014-07-08', 'Belo Horizonte' FROM dual UNION ALL
SELECT 4321, DATE '2014-08-09', 'Sao Paulo' FROM dual UNION ALL
SELECT 100, DATE '2014-09-10', 'Brasilia' FROM dual)
,table_teams(id_team, NAME, city) AS (
SELECT 'ARG', 'Argentina', 'Buenos Aires' FROM dual UNION ALL
SELECT 'BRA', 'Brazil', 'Sao Paulo' FROM dual UNION ALL
SELECT 'ENG', 'England', 'London' FROM dual UNION ALL
SELECT 'FRA', 'France', 'Paris' FROM dual UNION ALL
SELECT 'RUS', 'Russia', 'Moscow' FROM dual UNION ALL
SELECT 'USA', 'United States', 'New York' FROM dual)
-- End Test data
,match_teams AS (
SELECT id_match, MAX(id_team) team1, MIN(id_team) team2
FROM table_game
GROUP BY id_match
HAVING COUNT(*) = 2 -- any valid match should have only 2 teams, otherwise ignored
)
SELECT M.date_of_match, t1.NAME team1, g1.goals goals1, t2.NAME team2, g2.goals goals2, M.city city_match
FROM table_matches M
,match_teams mt
,table_game g1
,table_game g2
,table_teams t1
,table_teams t2
WHERE mt.id_match = M.id_match
AND g1.id_match = M.id_match
AND g1.id_team = mt.team1
AND g2.id_match = M.id_match
AND g2.id_team = mt.team2
AND t1.id_team = mt.team1
AND t2.id_team = mt.team2
/

you can use ROW_NUMBER to assign a value then join against it, something like this:
;with cte (team,match,goals,row) as
(
select
id_team,
id_match,
goals,
ROW_NUMBER () over (partition by match_id order by team_id)
from table_game
)
select
t1.date_of_match,c.team, c.goals, c1.goals, c1.team, t1.city
from cte c
left join cte c1 on c.match = c1.match and c1.row = 2
inner join table_matches t1 on c.match = t1.id_match
where c.row = 1

select date_of_match, g1.id_team team1, g1.goals goals1,
g2.goals goals2, g2.id_team team2, m.city
from matches m
join games g1 on g1.id_match = m.id_match
join games g2 on g1.id_match = m.id_match and g2.id > g1.id
test:
with games(id, id_team, id_match, goals) as (
select 1, 'GER', 1234, 7 from dual union all
select 2, 'BRA', 1234, 1 from dual),
matches(id_match, date_of_match, city) as (
select 1234, date '2014-07-08', 'Belo Horizonte' from dual)
select date_of_match, g1.id_team team1, g1.goals goals1,
g2.goals goals2, g2.id_team team2, m.city
from matches m
join games g1 on g1.id_match = m.id_match
join games g2 on g1.id_match = m.id_match and g2.id > g1.id
result:
DATE_OF_MATCH TEAM1 GOALS1 GOALS2 ID_TEAM CITY
------------- ------- ------ ------ ------- --------------------
2014-07-08 GER 7 1 BRA Belo Horizonte

Related

How to use multiple max Function in SQL select with left join

Suppose I have the following three tables:
Table1:
ID
Value_1
11
abc
22
def
33
xyz
Table2:
ID
Date_1
11
12-Mar-22
11
01-Jan-23
22
19-Dec-22
22
07-Feb-23
33
07-Mar-22
Table3:
ID
Length_1
11
574
11
1029
22
9220
33
1093
33
876
Now, I need an SQL query that would select each ID with Max Lenth_1 and Max Date_1.
Desired output:
ID
Value_1
Date_1
Length_1
11
abc
01-Jan-23
1029
22
def
07-Feb-23
9220
33
xyz
07-Mar-22
1093
I have used max() fuction to achieve this with left join between 2 tables together, however struggling when I have to use Max () twice with 3 tables. I am relatively new to SQL.
SQL Select Max(Date) out of rows with Duplicate Id
I tried this for two tables
Aggregate before you join the tables:
SELECT t1.id,
t1.value_1,
t2.date_1,
t3.length_1
FROM table1 t1
INNER JOIN (
SELECT id,
MAX(date_1) AS date_1
FROM table2
GROUP BY id
) t2
ON (t1.id = t2.id)
INNER JOIN (
SELECT id,
MAX(length_1) AS length_1
FROM table3
GROUP BY id
) t3
ON (t1.id = t3.id)
Which, for the sample data:
CREATE TABLE Table1 (ID, Value_1) AS
SELECT 11, 'abc' FROM DUAL UNION ALL
SELECT 22, 'def' FROM DUAL UNION ALL
SELECT 33, 'xyz' FROM DUAL;
CREATE TABLE Table2 (ID, Date_1) AS
SELECT 11, DATE '2022-03-12' FROM DUAL UNION ALL
SELECT 11, DATE '2023-01-01' FROM DUAL UNION ALL
SELECT 22, DATE '2022-12-19' FROM DUAL UNION ALL
SELECT 22, DATE '2023-02-07' FROM DUAL UNION ALL
SELECT 33, DATE '2022-03-07' FROM DUAL;
CREATE TABLE Table3 (ID, Length_1) AS
SELECT 11, 574 FROM DUAL UNION ALL
SELECT 11, 1029 FROM DUAL UNION ALL
SELECT 22, 9220 FROM DUAL UNION ALL
SELECT 33, 1093 FROM DUAL UNION ALL
SELECT 33, 876 FROM DUAL;
Outputs:
ID
VALUE_1
DATE_1
LENGTH_1
11
abc
2023-01-01 00:00:00
1029
22
def
2023-02-07 00:00:00
9220
33
xyz
2022-03-07 00:00:00
1093
fiddle
One option is to use subqueries selecting max values from tables 2 and 3:
Select t1.ID, t1.VALUE_1,
(Select Max(DATE_1) From Table2 Where ID = t1.ID) "DATE_1",
(Select Max(LENGTH_1) From Table3 Where ID = t1.ID) "LENGTH_1"
From Table1 t1
Order By t1.ID
... another one is to use analytic function with distinct keyword but it could be performance costly with big datasets:
Select DISTINCT
t1.ID, t1.VALUE_1, Max(t2.DATE_1) OVER(Partition By t1.ID) "DATE_1", Max(t3.LENGTH_1) OVER(Partition By t1.ID) "LENGTH_1"
From Table1 t1
Inner Join Table2 t2 ON(t2.ID = t1.ID)
Inner Join Table3 t3 ON(t3.ID = t1.ID)
Order By t1.ID
... both with your sample data:
WITH
Table1 (ID, VALUE_1) AS
(
Select 11, 'abc' From Dual Union All
Select 22, 'def' From Dual Union All
Select 33, 'xyz' From Dual
),
Table2 (ID, DATE_1) AS
(
Select 11, To_Date('2022-03-12', 'yyyy-mm-dd') From Dual Union All
Select 11, To_Date('2023-01-01', 'yyyy-mm-dd') From Dual Union All
Select 22, To_Date('2022-12-19', 'yyyy-mm-dd') From Dual Union All
Select 22, To_Date('2023-02-07', 'yyyy-mm-dd') From Dual Union All
Select 33, To_Date('2022-03-07', 'yyyy-mm-dd') From Dual
),
Table3 (ID, LENGTH_1) AS
(
Select 11, 574 From Dual Union All
Select 11, 1029 From Dual Union All
Select 22, 9220 From Dual Union All
Select 33, 1093 From Dual Union All
Select 33, 876 From Dual
)
results as:
ID VALUE_1 DATE_1 LENGTH_1
---------- ------- --------- ----------
11 abc 01-JAN-23 1029
22 def 07-FEB-23 9220
33 xyz 07-MAR-22 1093
Select t1.id, t1.value1, max(t2.date_1) date_1, max(t3.length_1)t3
from table_1 t1
left join table_2 t2 on t1.id=t2.id
left join table_3 t3 on t1.id=t3.id
group by t1.id, t1.value1
order by 1

SQL Lookup to another table to do aggregation and merge it back to the outer query

Query: Being able to do lookup from Table A to Table B and use an aggregation function based on date criteria referencing date fields from Table A with the date fields from Table B.
Scenario:
I have a car table (contains CAR_ID,Car_START_DT,Car_END_DT) and a car_payments table (contains CAR_ID, Car_Payment_DT, Car_Payment_Amt).
For every car in the car table, I would like to do a lookup into car_payments table using CAR_ID and aggregate by counting the number of Car_Payment_Amt records between the Car_START_DT and Car_END_DT (from car table) using Car_Payment_DT.
For my attempt, I created a subquery to COUNT(Car_Payment_Amt) GROUP BY CAR_ID under car_payments table and JOIN it with Car table based on CAR_ID to get the results but realized that the subquery will be taking longer than expected as the data size grow larger.
How can I do this efficiently using SQL? I did a search and people are saying that using correlated query but it has performance bottleneck. Are there any other options?
Just use a simple join
select
c.car_id, count(cp.payment_amt) as pmt_count
from
car c
left join
car_payment cp on cp.car_id = c.car_id
and cp.payment_dt between c.car_start_dt and c.car_end_date
group by
c.car_id
You can try it without grouping like here:
SELECT c.CAR_ID,
(Select Count(*) From payments
Where CAR_ID = c.CAR_ID And PAY_DATE Between c.START_DATE And c.END_DATE) "NO_OF_PAYS"
FROM cars c
which with following sample data:
WITH
cars (CAR_ID, START_DATE, END_DATE) AS
(
Select 1, To_Date('01.01.2023', 'dd.mm.yyyy'), To_Date('04.01.2023', 'dd.mm.yyyy') From Dual Union All
Select 2, To_Date('01.01.2023', 'dd.mm.yyyy'), To_Date('06.01.2023', 'dd.mm.yyyy') From Dual Union All
Select 3, To_Date('03.01.2023', 'dd.mm.yyyy'), To_Date('08.01.2023', 'dd.mm.yyyy') From Dual Union All
Select 4, To_Date('03.01.2023', 'dd.mm.yyyy'), To_Date('10.01.2023', 'dd.mm.yyyy') From Dual Union All
Select 5, To_Date('05.01.2023', 'dd.mm.yyyy'), To_Date('12.01.2023', 'dd.mm.yyyy') From Dual Union All
Select 6, To_Date('07.01.2023', 'dd.mm.yyyy'), To_Date('14.01.2023', 'dd.mm.yyyy') From Dual
),
payments (CAR_ID, PAY_DATE, AMAUNT) AS
(
Select 1, To_Date('01.01.2023', 'dd.mm.yyyy'), 100 From Dual Union All
Select 1, To_Date('03.01.2023', 'dd.mm.yyyy'), 100 From Dual Union All
Select 1, To_Date('05.01.2023', 'dd.mm.yyyy'), 100 From Dual Union All
Select 1, To_Date('06.01.2023', 'dd.mm.yyyy'), 100 From Dual Union All
Select 3, To_Date('05.01.2023', 'dd.mm.yyyy'), 300 From Dual Union All
Select 3, To_Date('08.01.2023', 'dd.mm.yyyy'), 300 From Dual Union All
Select 3, To_Date('11.01.2023', 'dd.mm.yyyy'), 300 From Dual Union All
Select 5, To_Date('11.01.2023', 'dd.mm.yyyy'), 500 From Dual Union All
Select 5, To_Date('13.01.2023', 'dd.mm.yyyy'), 500 From Dual Union All
Select 6, To_Date('06.01.2023', 'dd.mm.yyyy'), 600 From Dual Union All
Select 6, To_Date('12.01.2023', 'dd.mm.yyyy'), 600 From Dual
)
... results as
-- R e s u l t :
-- CAR_ID NO_OF_PAYS
-- ---------- ----------
-- 1 2
-- 2 0
-- 3 2
-- 4 0
-- 5 1
-- 6 1

How to filter records based on another grouped by column in a same table

I have a sample table as below:
Target output:
I have tried with below script but only number of count produced as output:
select ID, count(COUNTRY) from test
group by COUNTRY
having count(COUNTRY)=3;
Could anyone here please help how can I get the targeted output? Thanks.
Here's one option - a subquery:
Sample data:
SQL> with test (id, name, country) as
2 (select 1, 'Mike' , 'Australia' from dual union all
3 select 2, 'Jason', 'Australia' from dual union all
4 select 3, 'Lee' , 'China' from dual union all
5 select 4, 'Simon', 'India' from dual union all
6 select 5, 'Alex' , 'Malaysia' from dual union all
7 select 6, 'John' , 'Australia' from dual
8 )
Query:
9 select id, country
10 from test
11 where country in (select country
12 from test
13 group by country
14 having count(*) = 3
15 )
16 order by id;
ID COUNTRY
---------- ---------
1 Australia
2 Australia
6 Australia
SQL>
You can use analytic functions and only scan the table once:
SELECT id, name, country
FROM (
SELECT id, name, country,
COUNT(*) OVER (PARTITION BY country) AS people_per_country
FROM table_name
)
WHERE people_per_country = 3;
Which, for the sample data:
CREATE TABLE table_name (id, name, country) AS
SELECT 1, 'Mike' , 'Australia' FROM DUAL UNION ALL
SELECT 2, 'Jason', 'Australia' FROM DUAL UNION ALL
SELECT 3, 'Lee' , 'China' FROM DUAL UNION ALL
SELECT 4, 'Simon', 'India' FROM DUAL UNION ALL
SELECT 5, 'Alex' , 'Malaysia' FROM DUAL UNION ALL
SELECT 6, 'John' , 'Australia' FROM DUAL;
Outputs:
ID
NAME
COUNTRY
1
Mike
Australia
2
Jason
Australia
6
John
Australia
db<>fiddle here

How to get the max count of an attribute with 3 tables?

I need to query which author sold the most books and how many books the author sold.
select a.firstname ||''|| a.lastname as fullname,
max(count(datesold))
from author a,
transaction t,
book b
where a.authorid = b.authorid
and b.bookid = t.bookid
group by
a.firstname,
a.lastname;
It gave me an error of not a single-group group function.
Any idea what is the issue here?
With some sample data
SQL> with
2 author (authorid, firstname, lastname) as
3 (select 1, 'Stephen', 'King' from dual union all
4 select 2, 'Jo' , 'Nesbo' from dual),
5 book (bookid, authorid) as
6 (select 100, 1 from dual union all
7 select 200, 1 from dual union all
8 select 300, 2 from dual
9 ),
10 transaction (trans_id, bookid) as
11 (select 1, 100 from dual union all
12 select 2, 100 from dual union all
13 select 3, 100 from dual union all
14 select 4, 300 from dual
15 ),
query uses the RANK analytic function which ranks rows by number of rows in the transaction table (it says how many books were sold). Finally, fetch row(s) that rank as highest:
16 temp as
17 (select a.firstname || ' ' || a.lastname AS fullname,
18 count(t.bookid) cnt,
19 rank() over (order by count(t.bookid) desc) rnk
20 from author a join book b on a.authorid = b.authorid
21 join transaction t on t.bookid = b.bookid
22 group by a.firstname, a.lastname
23 )
24 select fullname, cnt
25 from temp
26 where rnk = 1;
FULLNAME CNT
------------- ----------
Stephen King 3
SQL>
You can use:
select MAX(a.firstname ||' '|| a.lastname) as fullname,
COUNT(datesold)
from author a
INNER JOIN book b
ON (a.authorid = b.authorid)
INNER JOIN transaction t
ON (b.bookid = t.bookid)
GROUP BY
a.authorid
ORDER BY
COUNT(datesold) DESC
FETCH FIRST ROW ONLY;
Do not aggregate by firstname and lastname as there are many people in the world with identical names and you do not want to count everyone with the same name as a single person.
Which, for the sample data:
CREATE TABLE author (authorid, firstname, lastname, dateofbirth) AS
SELECT 1, 'Alice', 'Adams', DATE '1900-01-01' FROM DUAL UNION ALL
SELECT 2, 'Alice', 'Adams', DATE '1910-01-01' FROM DUAL UNION ALL
SELECT 3, 'Betty', 'Baron', DATE '1920-01-01' FROM DUAL UNION ALL
SELECT 4, 'Carol', 'Corrs', DATE '1930-01-01' FROM DUAL UNION ALL
SELECT 5, 'Carol', 'Corrs', DATE '1940-01-01' FROM DUAL;
CREATE TABLE book (bookid, authorid) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL UNION ALL
SELECT 3, 3 FROM DUAL UNION ALL
SELECT 4, 4 FROM DUAL UNION ALL
SELECT 5, 5 FROM DUAL;
CREATE TABLE transaction (bookid, datesold) AS
SELECT 1, DATE '1970-01-01' FROM DUAL UNION ALL
SELECT 1, DATE '1970-01-02' FROM DUAL UNION ALL
SELECT 1, DATE '1970-01-03' FROM DUAL UNION ALL
SELECT 1, DATE '1970-01-04' FROM DUAL UNION ALL
SELECT 3, DATE '1970-01-01' FROM DUAL UNION ALL
SELECT 4, DATE '1970-01-01' FROM DUAL UNION ALL
SELECT 4, DATE '1970-01-02' FROM DUAL UNION ALL
SELECT 5, DATE '1970-01-01' FROM DUAL UNION ALL
SELECT 5, DATE '1970-01-02' FROM DUAL UNION ALL
SELECT 5, DATE '1970-01-03' FROM DUAL;
Outputs:
FULLNAME
COUNT(DATESOLD)
Alice Adams
4
db<>fiddle here

Group and exclude rows that had empty values aggregated - oracle sql

I have a oracle sql table that looks like so
"STUDENT_ID","FULL_NAME","SEMESTER_ID","STIP_ID"
"1","Liam Bottrill","1","1"
"1","Liam Bottrill","2","3"
"1","Liam Bottrill","3","2"
"1","Liam Bottrill","4","5"
"2","Maurits Smitham","1","6"
"2","Maurits Smitham","2",""
"2","Maurits Smitham","3","2"
"2","Maurits Smitham","4","6"
"43","Jackie Cotton","1",""
"43","Jackie Cotton","2",""
"43","Jackie Cotton","3",""
"43","Jackie Cotton","4",""
I want to group this table by "STUDENT_ID" and exclude from result any students that have any of "STIP_ID" rows empty
Im aiming for result like this:
"STUDENT_ID","FULL_NAME"
"1","Liam Bottrill"
Liam Bottrill should be displayed while Maurits Smitham and Jackie Cotton should be excluded from result
Can you please help me with such aggregate function?
Here is one way, using aggregation:
SELECT *
FROM yourTable
WHERE STUDENT_ID IN (
SELECT STUDENT_ID
FROM yourTable
GROUP BY STUDENT_ID
HAVING COUNT(CASE WHEN STIP_ID IS NULL THEN 1 END) = 0
);
Another way, using exists logic:
SELECT t1.*
FROM yourTable t1
WHERE NOT EXISTS (
SELECT 1
FROM yourTable t2
WHERE t2.STUDENT_ID = t1.STUDENT_ID AND
t2.STIP_ID IS NULL
);
You can group by the identifier and then use conditional aggregation to find the student where the count when STIP_ID is NULL (which, in Oracle, is the same as an empty string):
SELECT student_id,
MAX(full_name) AS full_name
FROM table_name
GROUP BY student_id
HAVING COUNT(CASE WHEN stip_id IS NULL THEN 1 END) = 0;
Which, for your sample data:
CREATE TABLE table_name (STUDENT_ID, FULL_NAME, SEMESTER_ID, STIP_ID) AS
SELECT 1, 'Liam Bottrill', 1, 1 FROM DUAL UNION ALL
SELECT 1, 'Liam Bottrill', 2, 3 FROM DUAL UNION ALL
SELECT 1, 'Liam Bottrill', 3, 2 FROM DUAL UNION ALL
SELECT 1, 'Liam Bottrill', 4, 5 FROM DUAL UNION ALL
SELECT 2, 'Maurits Smitham', 1, 6 FROM DUAL UNION ALL
SELECT 2, 'Maurits Smitham', 2, NULL FROM DUAL UNION ALL
SELECT 2, 'Maurits Smitham', 3, 2 FROM DUAL UNION ALL
SELECT 2, 'Maurits Smitham', 4, 6 FROM DUAL UNION ALL
SELECT 43, 'Jackie Cotton', 1, NULL FROM DUAL UNION ALL
SELECT 43, 'Jackie Cotton', 2, NULL FROM DUAL UNION ALL
SELECT 43, 'Jackie Cotton', 3, NULL FROM DUAL UNION ALL
SELECT 43, 'Jackie Cotton', 4, NULL FROM DUAL;
Outputs:
STUDENT_ID
FULL_NAME
1
Liam Bottrill
db<>fiddle here