简体   繁体   English

Oracle 11g:如何将oracle表与自身结合起来?

[英]Oracle 11g: How to union an oracle table with itself?

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: 该查询分为3个步骤:

  1. The records are aggregated to create a single row per team and match. 汇总记录以为每个团队创建一行并匹配。 In that process, the score is assigned to one of the three columns set_1, set_2, set_3. 在该过程中,分数被分配给三个列set_1,set_2,set_3中的一个。
  2. Row numbers are assigned to each row, starting at 1 for each match. 行号分配给每一行,每个匹配从1开始。 The result is that one team is assigned 1 and the other one is assigned 2 (column team_no). 结果是一个团队被分配1,另一个团队被分配2(列team_no)。
  3. The resulting table is joined to itself, the left side for teams with no. 结果表连接到自身,左侧是没有的团队。 1 and the right side for teams with no. 1和没有的球队的右侧。 2 using the match (date and code) as the join condition. 2使用匹配(日期和代码)作为连接条件。 The result is one row per match with the names and scores of both teams. 结果是每场比赛一行,两队的名称和分数。

First, group the data by "date", code, "set" to LISTAGG the teams and the scores. 首先,按"date", code, "set"将数据分组到LISTAGG团队和分数。 Then pivot the results on the scores column. 然后在结果列上旋转结果。 Here's the SQL for it: 这是它的SQL:

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. 在SQL Fiddle上查看此查询。

I'd do sg like this, if the name of the table is let's say VOLLEYBALL: 我会这样做,如果表的名字让我们说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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM