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 选择与左连接,其中我们需要列中具有最旧值的行_Sql_Oracle_Left Join_Oracle Sqldeveloper_Common Table Expression - Fatal编程技术网

Sql 选择与左连接,其中我们需要列中具有最旧值的行

Sql 选择与左连接,其中我们需要列中具有最旧值的行,sql,oracle,left-join,oracle-sqldeveloper,common-table-expression,Sql,Oracle,Left Join,Oracle Sqldeveloper,Common Table Expression,想象一下下面的场景,我们有两个表。 一个表存储玩家的状态、创建日期和id,另一个表保存他们的登录活动 我想检索所有在N年前登录或从未登录的玩家。正如你所见,我们有一个id=4的玩家从未登录过游戏,所以我们也希望通过检查他的创建日期将他包括在我们的列表中 活动表中的一个玩家也可能有多个条目,因此我们的兴趣是只为该玩家带来具有[maxLoginDate

想象一下下面的场景,我们有两个表。 一个表存储玩家的状态、创建日期和id,另一个表保存他们的登录活动

我想检索所有在N年前登录或从未登录的玩家。正如你所见,我们有一个id=4的玩家从未登录过游戏,所以我们也希望通过检查他的创建日期将他包括在我们的列表中

活动表中的一个玩家也可能有多个条目,因此我们的兴趣是只为该玩家带来具有[maxLoginDate 我已经有了一个解决方案,但我渴望看到不同的方法

PLAYER_TABLE
--------------------------------------
|PlayerId |CreationDate | Status     |
--------------------------------------
|1        |01.01.2000     | ACTIVE   |
--------------------------------------
|2        |01.01.2019     | ACTIVE   |          
--------------------------------------
|3        |01.01.2001     | SUSPENDED|          
--------------------------------------
|4        |01.01.2004     | ACTIVE   |          
--------------------------------------

ACTIVITY_TABLE
-----------------------
|AccountId |LoginDate  |
-----------------------
|1        |01.01.2005 |
-----------------------
|1        |05.06.2007 |          
-----------------------
|2        |03.05.2010 |         
-----------------------
|3        |01.01.2018 |         
-----------------------

使用CTE公共表表达式具体化分析,并让我们基于单个日期进行筛选:

WITH CTE AS(
SELECT player.PlayerId
     , activity.ddt 
     , coalesce(max(Activity.Logindate) over (partition by Activity.AccountID), player.CreationDate) as  LastLoginOrCreation
FROM PLAYER_TABLE player
LEFT JOIN  ACTIVITY_TABLE activity
  ON activity.AccountId = player.PlayerId)

SELECT * 
FROM CTE 
WHERE player.status != 'SUSPENDED'
  and LastLoginOrCreation <= to_date('2015-01-01', 'yyyy-MM-dd') 
避免CTE消除内联选择,但仍需在两个日期进行筛选

SELECT player.PlayerId
     , activity.ddt 
     , coalesce(max(Activity.Logindate) over (partition by Activity.AccountID), player.CreationDate) as  LastLoginOrCreation
FROM PLAYER_TABLE player
LEFT JOIN  ACTIVITY_TABLE activity
  ON activity.AccountId = player.PlayerId
WHERE (player.CREATION_DATE <= to_date('2015-01-01', 'yyyy-MM-dd') 
   OR activity.LoginDate <= to_date('2015-01-01', 'yyyy-MM-dd'))
  AND player.status != 'SUSPENDED';

测试了您的第一个解决方案,您得到的结果如下:1 01.01.2005、1 01.01.2005、2 01.01.2018、2 01.01.2018;这是一个常见问题。它有一个标记:。我会用谷歌搜索你的标题,但是这个页面上的自动“相关”链接包含超过1000张选票&其他包括超过1000张选票。在考虑发帖之前,请总是用谷歌搜索你的问题/问题/目标的许多清晰、简洁和准确的措辞,有或没有你的特定字符串/名称,并阅读许多答案。如果你发布一个问题,请使用一个短语作为title.PS。此外,这些链接在你撰写问题时会提供给你。也请展示你能做什么。给出一个代码问题。大量的规格说明不涉及主题问题。