当前位置: 首页 > 知识库问答 >
问题:

Oracle SQL-如何选择和组合多行数据

林冥夜
2023-03-14

场景是,对于特定的日期范围,我需要返回字段值已更改(从和到日期)的所有行。更改后的字段值将以不同的颜色显示在屏幕上。

我可以返回特定时间段内发生更改的所有员工记录。但是,如果一个员工的记录在所选时间段内多次更改,我需要返回一个员工记录,并为每个不同的X_标志列返回一个组合值。1表示已发生更改,0表示未发生更改。

表DDL为:

CREATE TABLE "EMPLOYEE_DATA" 
   (    "EMPLOYEE_ID" NUMBER(20,0), 
    "EMPLOYEE_NAME" VARCHAR2(100 BYTE), 
    "EMPLOYEE_NAME_FLAG" NUMBER(1,0), 
    "EMPLOYEE_ROLE" VARCHAR2(100 BYTE), 
    "EMPLOYEE_ROLE_FLAG" NUMBER(1,0), 
    "EMPLOYEE_SALARY" VARCHAR2(100 BYTE), 
    "EMPLOYEE_SALARY_FLAG" NUMBER(1,0),  
    "DATE_VALID_FROM" DATE, 
    "DATE_VALID_TO" DATE, 
    "HAS_RECORD_CHANGED" NUMBER(1,0), 
    "CURRENT_ROW_IND" NUMBER(1,0)
   );

模拟数据是:

Insert into EMPLOYEE_DATA (EMPLOYEE_ID,EMPLOYEE_NAME,EMPLOYEE_NAME_FLAG,EMPLOYEE_ROLE,EMPLOYEE_ROLE_FLAG,EMPLOYEE_SALARY,EMPLOYEE_SALARY_FLAG, DATE_VALID_FROM,DATE_VALID_TO,HAS_RECORD_CHANGED,CURRENT_ROW_IND) values (1,'John Smith',0,'Associate',0,'1',0,to_date('01-FEB-17','DD-MON-RR'),to_date('28-FEB-17','DD-MON-RR'),0,0);
Insert into EMPLOYEE_DATA (EMPLOYEE_ID,EMPLOYEE_NAME,EMPLOYEE_NAME_FLAG,EMPLOYEE_ROLE,EMPLOYEE_ROLE_FLAG,EMPLOYEE_SALARY,EMPLOYEE_SALARY_FLAG, DATE_VALID_FROM,DATE_VALID_TO,HAS_RECORD_CHANGED,CURRENT_ROW_IND) values (2,'Katy Brown',0,'Team Leader',0,'7',0, to_date('01-FEB-17','DD-MON-RR'),to_date('28-FEB-17','DD-MON-RR'),0,0);
Insert into EMPLOYEE_DATA (EMPLOYEE_ID,EMPLOYEE_NAME,EMPLOYEE_NAME_FLAG,EMPLOYEE_ROLE,EMPLOYEE_ROLE_FLAG,EMPLOYEE_SALARY,EMPLOYEE_SALARY_FLAG, DATE_VALID_FROM,DATE_VALID_TO,HAS_RECORD_CHANGED,CURRENT_ROW_IND) values (2,'Katy Brown',0,'Team Leader',0,'7',0, to_date('01-APR-17','DD-MON-RR'),to_date('31-DEC-99','DD-MON-RR'),1,1);
Insert into EMPLOYEE_DATA (EMPLOYEE_ID,EMPLOYEE_NAME,EMPLOYEE_NAME_FLAG,EMPLOYEE_ROLE,EMPLOYEE_ROLE_FLAG,EMPLOYEE_SALARY,EMPLOYEE_SALARY_FLAG, DATE_VALID_FROM,DATE_VALID_TO,HAS_RECORD_CHANGED,CURRENT_ROW_IND) values (3,'Ian Jones',1,'Delivery Manager',1,'3',1, to_date('01-MAR-17','DD-MON-RR'),to_date('31-DEC-99','DD-MON-RR'),1,1);
Insert into EMPLOYEE_DATA (EMPLOYEE_ID,EMPLOYEE_NAME,EMPLOYEE_NAME_FLAG,EMPLOYEE_ROLE,EMPLOYEE_ROLE_FLAG,EMPLOYEE_SALARY,EMPLOYEE_SALARY_FLAG, DATE_VALID_FROM,DATE_VALID_TO,HAS_RECORD_CHANGED,CURRENT_ROW_IND) values (1,'John Smith',0,'Analyst',1,'1',0, to_date('01-MAR-17','DD-MON-RR'),to_date('31-MAR-17','DD-MON-RR'),1,0);
Insert into EMPLOYEE_DATA (EMPLOYEE_ID,EMPLOYEE_NAME,EMPLOYEE_NAME_FLAG,EMPLOYEE_ROLE,EMPLOYEE_ROLE_FLAG,EMPLOYEE_SALARY,EMPLOYEE_SALARY_FLAG, DATE_VALID_FROM,DATE_VALID_TO,HAS_RECORD_CHANGED,CURRENT_ROW_IND) values (1,'John Smith',0,'Analyst',0,'2',1, to_date('01-APR-17','DD-MON-RR'),to_date('31-DEC-99','DD-MON-RR'),1,1);

我的疑问是:

SELECT *
FROM EMPLOYEE_DATA
WHERE DATE_VALID_FROM <= TO_DATE('01/04/2017', 'dd/mm/yyyy') 
  AND DATE_VALID_TO >= TO_DATE('01/01/2017', 'dd/mm/yyyy')
  AND HAS_RECORD_CHANGED = '1'
ORDER BY EMPLOYEE_ID ASC, DATE_VALID_FROM ASC;

在最后一个查询中,我将添加以下行以返回当前记录和当前行\u IND='1'。我省略了这一点,以说明我需要如何组合“John Smith”记录的数据,以合并上一条记录和当前记录(John Smith)的员工\角色\标志员工\工资\标志

编辑-添加原始和目标结果。如果可能的话,我需要聚合以获得每个唯一员工的X_标志列的最大值。

原件

EMPLOYEE_ID    EMPLOYEE_NAME    EMPLOYEE_NAME_FLAG  EMPLOYEE_ROLE   EMPLOYEE_ROLE_FLAG  EMPLOYEE_SALARY EMPLOYEE_SALARY_FLAG    DATE_VALID_FROM DATE_VALID_TO   HAS_RECORD_CHANGED  CURRENT_ROW_IND
1              John Smith       0                   Associate               0                   1               0                   01-Feb-17         28-Feb-17     0                   0
2              Katy Brown       0                   Team Leader             0                   7               0                   01-Feb-17         28-Feb-17     0                   0
2              Katy Brown       0                   Team Leader             0                   7               0                   01-Apr-17         31-Dec-99     1                   1
3              Ian Jones        1                   Delivery Manager        1                   3               1                   01-Mar-17         31-Dec-99     1                   1
1              John Smith       0                   Analyst                 1                   0               0                   01-Mar-17         31-Mar-17     1                   0
1              John Smith       0                   Analyst                 0                   1               1                   01-Apr-17         31-Dec-99     1                   1

目标

EMPLOYEE_ID EMPLOYEE_NAME   EMPLOYEE_NAME_FLAG  EMPLOYEE_ROLE   EMPLOYEE_ROLE_FLAG  EMPLOYEE_SALARY EMPLOYEE_SALARY_FLAG    DATE_VALID_FROM DATE_VALID_TO   HAS_RECORD_CHANGED  CURRENT_ROW_IND
1           John Smith      0                   Analyst                     1                   1               1               01-Apr-17    31-Dec-99      1                   1
2           Katy Brown      0                   Team Leader                 0                   7               0               01-Apr-17    31-Dec-99      1                   1
3           Ian Jones       1                   Delivery Manager            1                   3               1               01-Mar-17    31-Dec-99      1                   1

共有2个答案

林绪
2023-03-14

如果可能的话,我需要聚合以获得每个唯一员工的X_标志列的最大值。

对于上述要求,groupby将起作用,对吗?

请查找以下查询以实现您的目标,

SELECT EMPLOYEE_ID
  , EMPLOYEE_NAME
  , MIN(EMPLOYEE_NAME_FLAG) EMPLOYEE_NAME_FLAG
  , EMPLOYEE_ROLE
  , MAX(EMPLOYEE_ROLE_FLAG) EMPLOYEE_ROLE_FLAG
  , MIN(EMPLOYEE_SALARY) EMPLOYEE_SALARY
  , MAX(EMPLOYEE_SALARY_FLAG) EMPLOYEE_SALARY_FLAG
  , MAX(DATE_VALID_FROM) DATE_VALID_FROM
  , MAX(DATE_VALID_TO) DATE_VALID_TO
  , HAS_RECORD_CHANGED
  , MAX(CURRENT_ROW_IND) CURRENT_ROW_IND
FROM EMPLOYEE_DATA
WHERE HAS_RECORD_CHANGED = 1
   AND DATE_VALID_FROM BETWEEN TO_DATE('01/01/2017', 'dd/mm/yyyy')
                             AND TO_DATE('01/04/2017', 'dd/mm/yyyy')
GROUP BY EMPLOYEE_ID
  , EMPLOYEE_NAME
  , EMPLOYEE_ROLE
  , HAS_RECORD_CHANGED
ORDER BY EMPLOYEE_ID ASC
  , DATE_VALID_FROM ASC;
杜烨伟
2023-03-14

考虑派生表,其中单元级查询与计算最大标志的聚合查询连接:

SELECT emp.*    
FROM
  (SELECT *
   FROM EMPLOYEE_DATA
   WHERE DATE_VALID_FROM BETWEEN TO_DATE('01/01/2017', 'dd/mm/yyyy')
                             AND TO_DATE('01/04/2017', 'dd/mm/yyyy')
     AND HAS_RECORD_CHANGED = 1
  ) AS emp

INNER JOIN
  (SELECT EMPLOYEE_ID, MAX(EMPLOYEE_NAME_FLAG) AS MAX_NAME_FLAG,
          MAX(EMPLOYEE_ROLE_FLAG) AS MAX_ROLE_FLAG, 
          MAX(EMPLOYEE_SALARY_FLAG) AS MAX_SALARY_FLAG
   FROM EMPLOYEE_DATA
   WHERE DATE_VALID_FROM BETWEEN TO_DATE('01/01/2017', 'dd/mm/yyyy')
                             AND TO_DATE('01/04/2017', 'dd/mm/yyyy')
     AND HAS_RECORD_CHANGED = 1
   GROUP BY EMPLOYEE_ID
  ) AS agg

ON emp.EMPLOYEE_ID = agg.EMPLOYEE_ID 
AND emp.EMPLOYEE_NAME_FLAG = agg.MAX_NAME_FLAG 
AND emp.EMPLOYEE_ROLE_FLAG = agg.MAX_ROLE_FLAG 
AND emp.EMPLOYEE_SALARY_FLAG = agg.MAX_SALARY_FLAG

ORDER BY emp.EMPLOYEE_ID ASC, emp.DATE_VALID_FROM ASC
 类似资料:
  • 我有一个大约15万行的表,我必须使用JavaQuartz Scheduler一次获取1000行。要求是一次限制1000行,然后再限制1000行等(与MySQL限制查询相同)。 我正在使用以下查询: 问题是上面的查询返回了我在结果集中不需要的额外列rownum,因为返回的数据被传递给MapListHandler(),后者返回将结果转换为JSON,并且我将此JSON传递给不期望额外rownum列的We

  • 问题内容: 在Symfony2和Doctrine中,我想执行一个返回计数和分组依据的查询。 这是我尝试过的。这是我要运行的SQL: 与我的实体: 这是我的PartieRepository 这是我得到的错误: 问题答案: 您可能要使用本机查询 只需根据需要添加任何具有/ where子句。 以下是我的结果: 第一个数组中缺少的原因是null 。 编辑 OP产生了意外的结果,因此这是一些故障排除步骤:

  • 问题内容: 如果我有以下div: 有没有一种方法可以定义表达“与AND 的div”这一想法的样式? 还是您只是简单地走了一条路 要么 问题答案: 在样式表中: 编辑:这些可能也有帮助: 并且,根据您的示例: 四年后进行编辑: 由于它已经过时了,人们一直在寻找它: 不要 在选择器中使用tagNames。比tagName添加不需要的筛选步骤要快。 仅在必须的地方在选择器中使用tagNames!

  • 问题内容: 我在API服务器上创建查询时有些卡住,我只想用修改后的跟踪数据进行响应。我有几列这样的表。 现在,我只想跟踪在上次获取的时间戳(作为API请求参数传递的音频指纹和上一次获取的时间戳的数组)之后进行更新的轨道。 (^^这是无效的查询,仅用于理解)。 谢谢 问题答案: 示例数据: 将参数放在查询中,并将其与表连接: 除了CTE,您还可以使用派生表:

  • 假设我有5个不同的列,< code>a、b、c、d、e,我选择了多行: 例子: 用户有 3 个帖子,因此它将在查询中选择 3 行。 我想对< code>a的所有行的值求和(当然还有其余的)。 例如 值 = 4 值=10 < code >第3行 值= 1 所以我需要把所有这些加起来得到15。 我知道使用< code>array_sum($ratings)来查找数组的总和,但前提是您选择了一个可以有多

  • 问题内容: 好的,通常我知道如果知道数组值(在这种情况下为1,2,3),您将执行以下操作: 但是我不知道数组的值,我只知道我要查找的值是“存储”在数组中的: 这不起作用。还有另一种方法吗? 问题答案: 使用FIND_IN_SET函数: