I have a table which looks like the following:
date code name score set
09/09/12 967873 Team A 24 1
09/09/12 967873 Team B 22 1
09/09/12 967873 Team A 21 2
09/09/12 967873 Team B 16 2
02/04/12 965454 Team X 21 1
02/04/12 965454 Team Y 19 1
02/04/12 965454 Team X 21 2
02/04/12 965454 Team Y 19 2
you guessed it right! it's a volleyball match! however, I would like my output to be in a single line. For example:
date code Teams Set-1 Set-2 Set-3
09/09/12 967873 Team A VS.Team B 24-22 21-16 -
and so on....
**Notice that the game could have a third set as well
I will need some kind of self join to refine the above format to the format that is easier for Users view...Let me know if you need more details.
Thanks,
The query could look like this:
with matches as (
select "DATE", code, name,
max(case when "SET" = 1 then score end) score_1,
max(case when "SET" = 2 then score end) score_2,
max(case when "SET" = 3 then score end) score_3,
row_number() over(partition by "DATE", code order by name) team_no
from games
group by "DATE", code, name
)
select a."DATE", a.code, a.name || ' vs. ' || b.name teams,
a.score_1 || '-' || b.score_1 set_1,
a.score_2 || '-' || b.score_2 set_2,
a.score_3 || '-' || b.score_3 set_3
from matches a
join matches b on a."DATE" = b."DATE" and a.code = b.code
where a.team_no = 1 and b.team_no = 2;
date and set are rather unfortunate column names.
The query works in 3 steps:
First, group the data by "date", code, "set"
to LISTAGG
the teams and the scores. Then pivot the results on the scores column. Here's the SQL for it:
WITH grouped AS (
SELECT
"date", code, "set",
LISTAGG(name, ' VS. ') WITHIN GROUP (ORDER BY name) AS teams,
LISTAGG(score, '-' ) WITHIN GROUP (ORDER BY name) AS score
FROM matches
GROUP BY
"date", code, "set"
)
, pivoted AS (
SELECT
"date", code, teams,
nvl("1", '-') AS set1,
nvl("2", '-') AS set2,
nvl("3", '-') AS set3
FROM grouped
PIVOT (
MAX(score) FOR "set" IN (1, 2, 3)
) p
)
SELECT * FROM pivoted
;
Please have a look at this query at SQL Fiddle too.
I'd do sg like this, if the name of the table is let's say VOLLEYBALL:
SELECT temp.date, temp.code,
temp.team1 || ' vs. ' || temp.team2 AS teams,
(SELECT v.score FROM volleyball v WHERE v.code = temp.code AND v.name = team1 AND v.set = 1) || '-' ||
(SELECT v.score FROM volleyball v WHERE v.code = temp.code AND v.name = team2 AND v.set = 1) AS set1,
(SELECT v.score FROM volleyball v WHERE v.code = temp.code AND v.name = team1 AND v.set = 2) || '-' ||
(SELECT v.score FROM volleyball v WHERE v.code = temp.code AND v.name = team2 AND v.set = 2) AS set2,
nvl((SELECT v.score FROM volleyball v WHERE v.code = temp.code AND v.name = team1 AND v.set = 3) || '-' ||
(SELECT v.score FROM volleyball v WHERE v.code = temp.code AND v.name = team2 AND v.set = 3)
, '-') AS set3 -- optional, if no results, then it will be a '-'
FROM
(SELECT v.date, v.code,
min(v.name) AS team1, max(v.name) AS team2
FROM volleyball v
GROUP BY v.date, v.code) temp;
This will result a one row summary.
To return the required results without needing a join, try:
select "date",
code,
min_name || ' VS. ' || max_name teams,
sum(case when "set" = 1 and name = min_name then score end) || '-' ||
sum(case when "set" = 1 and name = max_name then score end) "Set-1",
sum(case when "set" = 2 and name = min_name then score end) || '-' ||
sum(case when "set" = 2 and name = max_name then score end) "Set-2",
sum(case when "set" = 3 and name = min_name then score end) || '-' ||
sum(case when "set" = 3 and name = max_name then score end) "Set-3"
from (select g.*,
min(name) over (partition by "date", code) min_name,
max(name) over (partition by "date", code) max_name
from games)
group by "date", code
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.