【问题标题】:Oracle PL/SQL Merge Query Result into Table ColumnOracle PL/SQL 将查询结果合并到表列中
【发布时间】:2017-03-24 22:32:09
【问题描述】:

我有一个存储高尔夫相关数据的数据库。我正在尝试计算每个球场上每个洞的老鹰、小鸟、标准杆等的数量,并将数量插入到洞表中的相应属性中。

我可以编写查询来提取我想要的信息,但我不确定如何获取我的查询结果并将其合并到我的表孔中的相应记录中。我查看了 Oracle SQL 的 MERGE 文档,但没有取得任何成功。

这是我现在拥有的:

--Count all the birdies on holes 1-18 of course 538
select phs.course_id, phs.hole_num, count(*) from player_hole_score phs
join hole h on 
  phs.hole_num = h.hole_num and
  phs.course_id = h.course_id
  where phs.score = h.hole_par - 1 and phs.course_id = 538
  group by phs.hole_num, phs.course_id
  order by phs.course_id, phs.hole_num;

--Where the data needs to be inserted
select course_id, hole_num, hole_num_birdie from hole
where course_id = 538;

以下两个查询结果:

            Query 1                                     Query 2 (Table Hole)
+-----------+----------+----------+     +-----------+----------+-----------------+
| COURSE_ID | HOLE_NUM | COUNT(*) |     | COURSE_ID | HOLE_NUM | HOLE_NUM_BIRDIE |
+-----------+----------+----------+     +-----------+----------+-----------------+
|       538 |        1 |      103 |     |       538 |        1 |                 |
|       538 |        2 |       76 |     |       538 |        2 |                 |
|       538 |        3 |       42 |     |       538 |        3 |                 |
|       538 |        4 |       71 |     |       538 |        4 |                 |
|       538 |        5 |       82 |     |       538 |        5 |                 |
|       538 |        6 |       77 |     |       538 |        6 |                 |
|       538 |        7 |       90 |     |       538 |        7 |                 |
|       538 |        8 |       34 |     |       538 |        8 |                 |
|       538 |        9 |      188 |     |       538 |        9 |                 |
|       538 |       10 |       87 |     |       538 |       10 |                 |
|       538 |       11 |       53 |     |       538 |       11 |                 |
|       538 |       12 |       95 |     |       538 |       12 |                 |
|       538 |       13 |      137 |     |       538 |       13 |                 |
|       538 |       14 |       69 |     |       538 |       14 |                 |
|       538 |       15 |      170 |     |       538 |       15 |                 |
|       538 |       16 |      197 |     |       538 |       16 |                 |
|       538 |       17 |       56 |     |       538 |       17 |                 |
|       538 |       18 |       82 |     |       538 |       18 |                 |
+-----------+----------+----------+     +-----------+----------+-----------------+

如何从第一个查询结果中取出列 COUNT(*) 并使用计数来更新表 Hole 中的相应记录,以便得到如下结果:

+-----------+----------+-----------------+
| COURSE_ID | HOLE_NUM | HOLE_NUM_BIRDIE |
+-----------+----------+-----------------+
|       538 |        1 |             103 |
|       538 |        2 |              76 |
|       538 |        3 |              42 |
|       538 |        4 |              71 |
|       538 |        5 |              82 |
|       538 |        6 |              77 |
|       538 |        7 |              90 |
|       538 |        8 |              34 |
|       538 |        9 |             188 |
|       538 |       10 |              87 |
|       538 |       11 |              53 |
|       538 |       12 |              95 |
|       538 |       13 |             137 |
|       538 |       14 |              69 |
|       538 |       15 |             170 |
|       538 |       16 |             197 |
|       538 |       17 |              56 |
|       538 |       18 |              82 |
+-----------+----------+-----------------+

编辑:在听完 cmets 之后,听起来使用视图是解决此问题的最佳方法。我能够使用 mathguy 的代码将其合并到现有表中,但我不确定如何将该代码转换为视图。特别是,我无法为我的子查询分配别名这一事实让我很失望。

我有这段代码用于合并:

merge into hole
  using 
  (select phs.course_id, phs.hole_num, count(*) as ct from player_hole_score phs
    join hole h on 
      phs.hole_num = h.hole_num and
      phs.course_id = h.course_id
      where phs.score = h.hole_par - 1
      group by phs.hole_num, phs.course_id)
  q
  on (hole.course_id = q.course_id and hole.hole_num = q.hole_num)
  when matched 
    then update set hole.hole_num_birdie = q.ct

我认为创建视图会相似,但我现在的结果是 0。下面我需要更改什么?

create view hole_statistic as
    select 
    hh.course_id, 
    hh.hole_num,
      (select count(*) as ct from player_hole_score phs
        join hole h on 
          phs.hole_num = h.hole_num and
          phs.course_id = h.course_id
          where phs.score = h.hole_par -1
          group by h.course_id, h.hole_num)    
    as birdies 
    from hole hh  
  group by hh.course_id, hh.hole_num;

【问题讨论】:

  • 这并不难,但您确定要这样做吗?每天都有更多的事件要记录,你要一直更新表格吗?正常(且有效)的解决方案是编写一个 VIEW 来实时显示所有这些统计数据,并且始终保持最新状态。如果性能很重要,您可以“具体化”该视图,以便针对它的查询快速运行。
  • @mathguy 这是一个学校项目,我已经收集了所有数据,所以我不担心会记录更多事件。我想要一个更新声明,这样我就可以更新所有数量,而不必对它做任何其他事情。

标签: sql oracle oracle11g


【解决方案1】:
merge into hole
  using (   your query here   ) q
  on (hole.course_id = q.course_id and hole.hole_num = q.hole_num)
when matched
  then update set hole.hole_num_birdie = q.ct
where hole.course_id = 538  --  this is optional, you can update all at once

your query here 是您的第一个查询,减去不需要的 ORDER BY 子句。请注意,MERGE 语句中的别名为 q

在第一个查询中,您需要为count(*) 列提供一个别名:count(*) as ct

不过,在您这样做之前,请考虑一下我在您原始帖子下的评论中所说的话。

【讨论】:

  • 感谢使用合并的代码,这也正是我所需要的。我对上面的帖子进行了编辑,以使用视图执行相同的操作。你知道我在上面的尝试中需要修改什么吗?
  • @EricPratt - 我不确定我是否理解你的问题。视图创建应该非常简单 - CREATE VIEW <your_view_name> AS SELECT .......(查询的其余部分)。您可能不需要 WHERE 子句,请在创建视图时将其排除在查询之外。稍后,当您需要查询此视图时,您可以说“select ... from WHERE ....”并将 course_id 和 hole_id 添加到此查询中针对视图。
【解决方案2】:

如果性能不是问题,我会使用视图而不是插入表格。

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 2023-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 2021-09-06
    相关资源
    最近更新 更多