Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按不在Oracle中工作分组_Sql_Oracle_Join - Fatal编程技术网

Sql 按不在Oracle中工作分组

Sql 按不在Oracle中工作分组,sql,oracle,join,Sql,Oracle,Join,我有两个表-CALL和ACTIONS\u HISTORY-其中ACTIONS\u HISTORY包含与每个调用相关的操作。并非每次呼叫都有一个操作 我想为我的每个通话选择最近的操作。以下是我当前的SQL: SELECT CALL.CALL_ID, ACTIONS_HISTORY_ID FROM ACTIONS_HISTORY RIGHT JOIN CALL ON ACTIONS_HISTORY.CALL_ID = CALL.CALL_ID GROUP

我有两个表-CALL和ACTIONS\u HISTORY-其中ACTIONS\u HISTORY包含与每个调用相关的操作。并非每次呼叫都有一个操作

我想为我的每个通话选择最近的操作。以下是我当前的SQL:

    SELECT CALL.CALL_ID,
           ACTIONS_HISTORY_ID
      FROM ACTIONS_HISTORY
RIGHT JOIN CALL ON ACTIONS_HISTORY.CALL_ID = CALL.CALL_ID
  GROUP BY CALL.CALL_ID, ACTIONS_HISTORY_ID
此SQL还返回相同的结果:

    SELECT DISTINCT
           CALL.CALL_ID,
           ACTIONS_HISTORY_ID
      FROM ACTIONS_HISTORY
RIGHT JOIN CALL ON ACTIONS_HISTORY.CALL_ID = CALL.CALL_ID
出于某些原因,这不会删除任何额外的行,例如,一个调用返回两个实例,因为它有两个相关的操作。我犯的明显错误是什么

编辑:这段代码运行了一段时间,但现在返回重复的行(不确定错误是什么)


分组依据
用于聚合,而不是删除重复项。如果要删除重复,请使用
distinct


要获得最大值,需要使用
max
聚合显式请求它。在这种情况下,您也没有按两列进行分组。如果您的数据确实以可预测的方式随时间增加,则您可能需要更复杂的查询来获取所需信息。

分组依据是用于聚合,而不是删除重复项。如果要删除重复,请使用
distinct


要获得最大值,需要使用
max
聚合显式请求它。在这种情况下,您也没有按两列进行分组。如果您的数据确实以可预测的方式随着时间的推移而增加,则可能需要更复杂的查询来获取所需的内容。

正如Donnie所建议的,GROUP BY用于聚合。您需要在SELECT子句中使用聚合函数,例如

SELECT
    CALL.CALL_ID,
    MAX(ACTIONS_HISTORY_ID) ACTIONS_HISTORY_ID
...
如果您的ID是单调递增的,那么这将实现您的目标


编辑:然后您应该只按呼叫进行分组_ID

,正如Donnie所建议的,分组是用于聚合的。您需要在SELECT子句中使用聚合函数,例如

SELECT
    CALL.CALL_ID,
    MAX(ACTIONS_HISTORY_ID) ACTIONS_HISTORY_ID
...
如果您的ID是单调递增的,那么这将实现您的目标


编辑:然后您应该只按调用进行分组\u ID

我没有在这台计算机上安装Oracle,因此我无法进行测试,但以下操作应该可以。你会接到每一个电话,以及最近的行动(有最长的日期)。我认为rn即使对于没有操作的调用也是1,但您必须进行测试

with ranked as(
    SELECT CALL.CALL_ID
          ,ACTIONS_HISTORY_ID
          ,row_number() over(partition by CALL.CALL_ID 
                                 order by ACTIONS_HISTORY_DT desc) as rn
      FROM ACTIONS_HISTORY
    RIGHT JOIN CALL ON ACTIONS_HISTORY.CALL_ID = CALL.CALL_ID
)
select *
  from ranked
 where rn = 1;

我没有在这台计算机上安装Oracle,所以我无法测试,但以下应该可以工作。你会接到每一个电话,以及最近的行动(有最长的日期)。我认为rn即使对于没有操作的调用也是1,但您必须进行测试

with ranked as(
    SELECT CALL.CALL_ID
          ,ACTIONS_HISTORY_ID
          ,row_number() over(partition by CALL.CALL_ID 
                                 order by ACTIONS_HISTORY_DT desc) as rn
      FROM ACTIONS_HISTORY
    RIGHT JOIN CALL ON ACTIONS_HISTORY.CALL_ID = CALL.CALL_ID
)
select *
  from ranked
 where rn = 1;

虽然其他人提到使用递增序列的MAX(),但如果可能,最好避免这样做。由于您的ACTIONS_HISTORY_DT具有实际的日期值,因此这是一个更好的候选者(此列上的索引将有助于提高性能)

当序列在技术上不再按升序排列时,对序列使用MAX()可能会在开发人员无法控制的某些情况下(例如,移动到集群数据库)中断查询

此外,还可以使用分析函数来减少对自联接的需要。看见 有关更多信息,请访问oracle.com

我建议这样问:

  WITH recent_actions AS
      (SELECT DISTINCT ah.call_id,
         FIRST_VALUE(ah.actions_history_id) OVER 
          (PARTITION BY ah.call_id 
           ORDER BY ah.actions_history_dt DESC ROWS UNBOUNDED PRECEDING
          ) AS latest_action_id
       FROM actions_history ah)
   SELECT c.call_id, r.latest_action_id
     FROM call c
LEFT JOIN recent_actions r ON(r.call_id = c.call_id);
由于查询使用公共表表达式(CTE)提取调用\u ID和最新操作\u历史\u ID,因此如果需要查询中返回的历史记录中的更多列,可以使用这些ID向操作\u历史记录添加另一个外部联接:

  WITH recent_actions AS
      (SELECT DISTINCT ah.call_id,
         FIRST_VALUE(ah.actions_history_id) OVER 
          (PARTITION BY ah.call_id 
           ORDER BY ah.actions_history_dt DESC ROWS UNBOUNDED PRECEDING
          ) AS latest_action_id
       FROM actions_history ah)
   SELECT c.call_id, r.latest_action_id, h.description, h.duration, h.caller_id
     FROM call c
LEFT JOIN recent_actions r ON(r.call_id = c.call_id)
LEFT JOIN actions_history h ON(h.actions_history_id = r.latest_action_id;

虽然其他人提到使用递增序列的MAX(),但如果可能,最好避免这样做。由于您的ACTIONS_HISTORY_DT具有实际的日期值,因此这是一个更好的候选者(此列上的索引将有助于提高性能)

当序列在技术上不再按升序排列时,对序列使用MAX()可能会在开发人员无法控制的某些情况下(例如,移动到集群数据库)中断查询

此外,还可以使用分析函数来减少对自联接的需要。看见 有关更多信息,请访问oracle.com

我建议这样问:

  WITH recent_actions AS
      (SELECT DISTINCT ah.call_id,
         FIRST_VALUE(ah.actions_history_id) OVER 
          (PARTITION BY ah.call_id 
           ORDER BY ah.actions_history_dt DESC ROWS UNBOUNDED PRECEDING
          ) AS latest_action_id
       FROM actions_history ah)
   SELECT c.call_id, r.latest_action_id
     FROM call c
LEFT JOIN recent_actions r ON(r.call_id = c.call_id);
由于查询使用公共表表达式(CTE)提取调用\u ID和最新操作\u历史\u ID,因此如果需要查询中返回的历史记录中的更多列,可以使用这些ID向操作\u历史记录添加另一个外部联接:

  WITH recent_actions AS
      (SELECT DISTINCT ah.call_id,
         FIRST_VALUE(ah.actions_history_id) OVER 
          (PARTITION BY ah.call_id 
           ORDER BY ah.actions_history_dt DESC ROWS UNBOUNDED PRECEDING
          ) AS latest_action_id
       FROM actions_history ah)
   SELECT c.call_id, r.latest_action_id, h.description, h.duration, h.caller_id
     FROM call c
LEFT JOIN recent_actions r ON(r.call_id = c.call_id)
LEFT JOIN actions_history h ON(h.actions_history_id = r.latest_action_id;

我想你在找我


我想你在找我


我尝试了这个,但结果相同(我将修改我的问题以显示我尝试过的查询)我尝试了这个,但结果相同(我将修改我的问题以显示我尝试过的查询)如何确定最近的查询?你有行动日期栏吗?或者我们可以通过动作\u历史\u ID(较大的nr=最近的)来确定这一点吗?动作\u历史\u DT包含事件的日期/时间。但是,由于ID是增量的,所以可以使用ID来完成。如何确定最新的ID?你有行动日期栏吗?或者我们可以通过动作\u历史\u ID(较大的nr=最近的)来确定这一点吗?动作\u历史\u DT包含事件的日期/时间。它可以使用ID来完成,但是因为它是增量的。我好像又把它弄坏了。它仍然会返回重复的行(更新的问题)。您需要了解分组和聚合是如何工作的,而不是盲目地进行随机更改并希望获得最佳结果。您当前的查询返回调用id和操作描述的每个组合的最大操作id,当然,这将是每个操作,而不仅仅是最近的一个。我似乎再次打破了它。它仍然会返回重复的行(更新的问题)。您需要了解分组和聚合是如何工作的,而不是盲目地进行随机更改并希望获得最佳结果。您当前的查询返回调用id和操作描述的每个组合的最大操作id,当然,这将是每个操作,而不仅仅是最近的一个。