I want to select information from two SQL tables within one query, the information is unrelated though, so no potential joints exist.
An example could be the following setup.
tblMadrid
id | name | games | goals
1 | ronaldo | 100 | 100
2 | benzema | 50 | 25
3 | bale | 75 | 50
4 | kroos | 80 | 10
tblBarcelona
id | name | games | goals
1 | neymar | 60 | 25
2 | messi | 150 | 200
3 | suarez | 80 | 80
4 | iniesta | 40 | 5
I want to have a query that gives me the following:
name | games | goals
messi | 150 | 200
ronaldo | 100 | 100
I tried to follow this logic: Multiple select statements in Single query but the following code did not work:
USE Liga_BBVA
SELECT (SELECT name,
games,
goals
FROM tblMadrid
WHERE name = 'ronaldo') AS table_a,
(SELECT name,
games,
goals
FROM tblBarcelona
WHERE name = 'messi') AS table_b
ORDER BY goals
Any advice on this one? Thanks
Info: The football stuff is just a simplifying example. In reality it is not possible to put both tables into one and have a new "team" column. The two tables have completely different structures, but I need something that matches the characteristics of this example.
You can do something like this:
(SELECT
name, games, goals
FROM tblMadrid WHERE name = 'ronaldo')
UNION
(SELECT
name, games, goals
FROM tblBarcelona WHERE name = 'messi')
ORDER BY goals;
See, for example: https://dev.mysql.com/doc/refman/5.0/en/union.html
If you like to keep records separate and not do the union.
Try query below
SELECT (SELECT name,
games,
goals
FROM tblMadrid
WHERE name = 'ronaldo') AS table_a,
(SELECT name,
games,
goals
FROM tblBarcelona
WHERE name = 'messi') AS table_b
FROM DUAL
The UNION statement is your friend:
SELECT a.playername, a.games, a.goals
FROM tblMadrid as a
WHERE a.playername = "ronaldo"
UNION
SELECT b.playername, b.games, b.goals
FROM tblBarcelona as b
WHERE b.playername = "messi"
ORDER BY goals;
You can union the queries as long as the columns match.
SELECT name,
games,
goals
FROM tblMadrid
WHERE id = 1
UNION ALL
SELECT name,
games,
goals
FROM tblBarcelona
WHERE id = 2
You can combine data from the two tables, order by goals highest first and then choose the top two like this:
MySQL
select *
from (
select * from tblMadrid
union all
select * from tblBarcelona
) alldata
order by goals desc
limit 0,2;
SQL Server
select top 2 *
from (
select * from tblMadrid
union all
select * from tblBarcelona
) alldata
order by goals desc;
If you only want Messi and Ronaldo
select * from tblBarcelona where name = 'messi'
union all
select * from tblMadrid where name = 'ronaldo'
To ensure that messi is at the top of the result, you can do something like this:
select * from (
select * from tblBarcelona where name = 'messi'
union all
select * from tblMadrid where name = 'ronaldo'
) stars
order by name;
select name, games, goals
from tblMadrid where name = 'ronaldo'
union
select name, games, goals
from tblBarcelona where name = 'messi'
ORDER BY goals
Using union will help in this case.
You can also use join on a condition that always returns true and is not related to data in these tables.See below
select tmd .name,tbc.goals from tblMadrid tmd join tblBarcelona tbc on 1=1;
join will help you even in case when tables do not have common columns
You can use UNION in this case
select id, name, games, goals from tblMadrid
union
select id, name, games, goals from tblBarcelona
you jsut have to maintain order of selected columns ie id, name, games, goals in both SQLs
as i see you want most goals in each team
you can try this
select name,games,max(goals) as 'most goals' from tblRealMadrid
union
select name,games,max(goals) as 'most goals' from tblBarcelona
In your case, the two tables have completely different structures and cannot be joined.
The UNION operator could be used. The UNION operator joins the results of two or more SELECT statements to produce a single result set. The first column in the SELECT statement is used to sort the result set.
SELECT name, games, goals
FROM tblMadrid
WHERE name = 'ronaldo'
UNION
SELECT name, games, goals
FROM tblBarcelona
WHERE name = 'messi'
ORDER BY goals;
Each SELECT statement must have the same number of columns and data types that are compatible. Also, if you want to keep the duplicates, use UNION ALL rather than UNION.
Related
i need to create an oracle select statement that returns acct,name,city,splitcost from table1 and APIcost from table2. table1 splits the 90 into 3 diff. amounts because they are distributed elsewhere. table2 is the API download that only has 1 record of the total 90. if i use inner join the 90 repeats on each row linking by acct. i need the results to look like the second view only show APIcost total 90. once per acct.
hope this makes sense. if i was using sql I'm prob. do a temp table but it has to be done in Oracle which i'm not used too.
No need for a temp table, just build a rank and do a case statement on it to populate the first row with the api_cost. I don't know which row you want, so play with the "order by" clause to get that to do the row you want.
/* Building out your data to a "temp table" */
with table1 as
(select 1111 as acct, 'john' as name, 'hampton' as city, 30 as split_cost, 90 as
api_cost from dual union all
select 1111 as acct, 'john' as name, 'hampton' as city, 40 as split_cost, 90 as
api_cost from dual union all
select 1111 as acct, 'john' as name, 'hampton' as city, 20 as split_cost, 90 as
api_cost from dual union all
select 1111 as acct, 'john' as name, 'hampton' as city, 20 as split_cost, 90 as
api_cost from dual)
/* You need nothing above here, just below */
select acct, name, city, split_cost,
case when rank() over (partition by acct, name, city order by split_cost, rownum) =
1 then api_cost
else null
end as api_cost
from table1; --substitute your table name here
OUTPUT:
ACCT NAME CITY SPLIT_COST API_COST
1111 john hampton 20 90
1111 john hampton 20
1111 john hampton 30
1111 john hampton 40
Imagine I have two tables, food and people, and I indicate who likes which food with a link table. So:
foods
-----
sausages
pie
Mars bar
people
------
john
paul
george
ringo
person | food (link table)
-------+-----
john | pie
john | sausage
paul | sausage
I'd like to get a list of foods, along with a person who likes that food. So I'd like a table like this:
food | a randomly chosen liker
---------+------------------------
sausage | john (note: this could be "paul" instead)
pie | john (note: must be john; he's the only liker)
Mars bar | null (note: nobody likes it)
Is it possible to do this in one query?
Obviously, I can do:
select
f.food, p.person
from
food f inner join link l
on f.food = l.food
inner join person p
on l.person = p.person
but that will give me two sausage rows, because two people like it, and I'll have to deduplicate the rows myself.
Do LEFT JOINs to also get food that no-one likes. GROUP BY to get each food only once, use MIN to pick first person that likes that food.
select f.food, min(p.person)
from food f
left join linktable l on f.id = l.food_id
left join people p on p.id = l.person_id
group by f.food
select f.food, min(l.person)
from food f
left join link l on f.foods = l.food
group by f.food
I would use a partition to do that, example:
WITH ORDERED AS
(
SELECT
PERSON,
FOOD,
ROW_NUMBER() OVER (PARTITION BY lower(FOOD) ORDER BY lower(PERSON) DESC) AS RN
FROM
(
SELECT 'john' AS PERSON ,'pie' AS FOOD FROM DUAL UNION
SELECT 'john1' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john2' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john3' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john4' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john5' AS PERSON ,'eggs' AS FOOD FROM DUAL UNION
SELECT 'john6' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'dada' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'paul' AS PERSON ,'sausage' AS FOOD FROM DUAL
-- Your select statement here that links the two tables
) PERSON_FOOD
)
SELECT
FOOD,
PERSON
FROM
ORDERED
WHERE
RN = 1
This will get you the following:
FOOD | PERSON
-------------------
eggs | john
pie | john
sausage | paul
This is in oracle syntax
Another variant.. (Assuming it is SQL Server )
Select
a.Food, b.Person
from
foods a
outer apply
(
Select top 1 Person from linkTable b where a.Food = b.Food
) b
Imagine I have two tables, food and people, and I indicate who likes which food with a link table. So:
foods
-----
sausages
pie
Mars bar
people
------
john
paul
george
ringo
person | food (link table)
-------+-----
john | pie
john | sausage
paul | sausage
I'd like to get a list of foods, along with a person who likes that food. So I'd like a table like this:
food | a randomly chosen liker
---------+------------------------
sausage | john (note: this could be "paul" instead)
pie | john (note: must be john; he's the only liker)
Mars bar | null (note: nobody likes it)
Is it possible to do this in one query?
Obviously, I can do:
select
f.food, p.person
from
food f inner join link l
on f.food = l.food
inner join person p
on l.person = p.person
but that will give me two sausage rows, because two people like it, and I'll have to deduplicate the rows myself.
Do LEFT JOINs to also get food that no-one likes. GROUP BY to get each food only once, use MIN to pick first person that likes that food.
select f.food, min(p.person)
from food f
left join linktable l on f.id = l.food_id
left join people p on p.id = l.person_id
group by f.food
select f.food, min(l.person)
from food f
left join link l on f.foods = l.food
group by f.food
I would use a partition to do that, example:
WITH ORDERED AS
(
SELECT
PERSON,
FOOD,
ROW_NUMBER() OVER (PARTITION BY lower(FOOD) ORDER BY lower(PERSON) DESC) AS RN
FROM
(
SELECT 'john' AS PERSON ,'pie' AS FOOD FROM DUAL UNION
SELECT 'john1' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john2' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john3' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john4' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'john5' AS PERSON ,'eggs' AS FOOD FROM DUAL UNION
SELECT 'john6' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'dada' AS PERSON ,'sausage' AS FOOD FROM DUAL UNION
SELECT 'paul' AS PERSON ,'sausage' AS FOOD FROM DUAL
-- Your select statement here that links the two tables
) PERSON_FOOD
)
SELECT
FOOD,
PERSON
FROM
ORDERED
WHERE
RN = 1
This will get you the following:
FOOD | PERSON
-------------------
eggs | john
pie | john
sausage | paul
This is in oracle syntax
Another variant.. (Assuming it is SQL Server )
Select
a.Food, b.Person
from
foods a
outer apply
(
Select top 1 Person from linkTable b where a.Food = b.Food
) b
I'm making an app that shows people movies to rate, a-la hot-or-not. I'd like to write a query that gets me the number of times a movie has been rated. The table for ratings looks like this:
| id | winner | loser |
| 1 | 1 | 2 |
| 2 | 2 | 3 |
| 3 | 1 | 3 |
I can get the number of times a movie has "won" by running a query like this:
SELECT winner, count(winner) AS number_of_wins
FROM movie_results
GROUP BY winner
ORDER BY number_of_wins DESC;
But I'd like to get another query that shows the total number of times a movie was pitched against other movies, i.e. the number of times a movie has appeared to be rated, whether it was rated above or below the other movie. What is the easiest way to achieve this, using only SQL queries?
Here is one method, using union all:
select movie, count(*) as nummatches, sum(win) as numwins
from ((select winner as movie, 1 as win from match_results) union all
(select loser, 0 from match_results)
) wl
group by movie;
You can do a full join between two derived tables where each table contains the number of losses and wins for each player.
select
coalesce(winner,loser) player,
coalesce(number_of_wins,0) number_of_wins,
coalesce(number_of_losses,0) number_of_losses,
coalesce(number_of_wins,0) + coalesce(number_of_losses,0) number_of_matches
from (
select winner, count(*) number_of_wins
from movie_results
group by winner
) winners full join (
select loser, count(*) number_of_losses
from movie_results
group by loser
) losers on losers.loser = winners.winner
http://sqlfiddle.com/#!15/980d6/3
This question already has answers here:
How to select records with maximum values in two columns?
(2 answers)
Closed 7 years ago.
I have the following table :
**Country Name Number**
us John 45
us Jeff 35
fr Jean 31
it Luigi 25
fr Maxime 23
ca Justin 23
This table is order by Number. I want to have a query that for each country give me the name with highest number :
**Country Name Number**
us John 45
fr Jean 31
it Luigi 25
ca Justin 23
I try to use distinct but I can't only make it on country if I want to print the all thing...
Have an idea ?'
EDIT :
The table is obtain by a subquery
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE Countries AS
SELECT 'us' AS Country, 'John' AS Name, 45 AS "Number" FROM DUAL
UNION ALL SELECT 'us' AS Country, 'Jeff' AS Name, 35 AS "Number" FROM DUAL
UNION ALL SELECT 'fr' AS Country, 'Jean' AS Name, 31 AS "Number" FROM DUAL
UNION ALL SELECT 'it' AS Country, 'Luigi' AS Name, 25 AS "Number" FROM DUAL
UNION ALL SELECT 'fr' AS Country, 'Maxime' AS Name, 23 AS "Number" FROM DUAL
UNION ALL SELECT 'ca' AS Country, 'Justin' AS Name, 23 AS "Number" FROM DUAL;
Query 1:
SELECT Country,
MAX( Name ) KEEP ( DENSE_RANK FIRST ORDER BY "Number" DESC ) AS "Name",
MAX( "Number" ) AS "Number"
FROM Countries
GROUP BY Country
Results:
| COUNTRY | Name | Number |
|---------|--------|--------|
| ca | Justin | 23 |
| fr | Jean | 31 |
| it | Luigi | 25 |
| us | John | 45 |
I do not have an Oracle db handy but I got this working in my SQL Server db and am pretty sure it will work in Oracle (meaning I think I am using ANSI sql which should work in most db's):
SELECT m.Country,m.Name,m.number
FROM mytable m
INNER JOIN (
select country, MAX(number) as number
FROM mytable GROUP BY Country
) AS tmp ON m.Country = tmp.Country and m.Number = tmp.number
ORDER BY m.Number DESC
This has the added benefit that it should give you records when you have two people in a given country that have the same number.
You didn't give us a table name so I just called it mytable.
Try below query:
SELECT Country, MAX(numbeer) FROM Table_Name GROUP BY Country
PFB updated query to include Name:
SELECT t1.* FROM table1 t1 INNER JOIN
(SELECT country, max(numbeer) as numbeer FROM table1 GROUP BY country) t2
ON t1.country=t2.country AND t1.numbeer=t2.numbeer;
Use row_number():
select t.Country, t.Name, t.Number
from (select t.*,
row_number() over (partition by country order by number desc) as seqnum
from table t
) t
where seqnum = 1;