自联接同一张表以将共享子字符串的行分组在一起

时间:2019-07-03 22:17:59

标签: sql oracle

我有一个表,该表具有多个行,这些行在某个列中共享一个子字符串,我想将它们分组在一起。

例如我可能有

ID | Service     | Function
__________________________________________
 1 | abc1234hgf  | Create
 2 | bvc8554mnb  | Create
 3 | cxz1234poi  | Update

我正在尝试将查询写到对共享服务中数字子字符串的行进行分组(在本示例中为1234)并且同时具有更新和创建条目,因此这将是结果:

ID  | Service | Function
________________________
 1  | 1234    |  Create
 3  | 1234    |  Update

所以我尝试编写一个进行自我连接的查询,因为Update仅在已经存在创建行的情况下才会发生,因此我认为我可以倒退:查找具有Update条目的行,从那里获取服务子字符串,并将其连接到找到其余的创造物。

SELECT a.id, a.service, a.function
FROM audits a
INNER JOIN audits b
ON a.service = SUBSTR(b.service, 4, 8);

现在,这使我将所有4位数字组合在一起,但是我想缩小('update','create')中的WHERE函数。当我尝试任何一个时,尽管我都为空。

我在正确的位置吗?

3 个答案:

答案 0 :(得分:2)

您可以使用EXISTS进行此操作:

SELECT a.id, SUBSTR(a.service, 4, 8) as service, a.function
FROM audits a
WHERE a.function IN ('create', 'update') AND
      EXISTS (SELECT 1
              FROM audits a2
              WHERE SUBSTR(a2.service, 4, 8) = SUBSTR(a.service, 4, 8) AND
                    a2.function IN ('create', 'update') AND
                    a2.function <> a.function
             );

答案 1 :(得分:0)

您不需要加入;相反,您可以使用分析功能在单个表扫描中完成此操作:

Oracle设置

CREATE TABLE audits ( ID, Service, Function ) AS
  SELECT 1, 'abc1234hgf', 'Create' FROM DUAL UNION ALL
  SELECT 2, 'bvc8554mnb', 'Create' FROM DUAL UNION ALL
  SELECT 3, 'cxz1234poi', 'Update' FROM DUAL

查询

SELECT id,
       service,
       function
FROM   (
  SELECT id,
         SUBSTR( service, 4, 4 ) AS service,
         function,
         COUNT( CASE function WHEN 'Create' THEN 1 END )
           OVER ( PARTITION BY SUBSTR( service, 4, 4 ) ) AS num_create,
         COUNT( CASE function WHEN 'Update' THEN 1 END )
           OVER ( PARTITION BY SUBSTR( service, 4, 4 ) ) AS num_update
  FROM   audits
)
WHERE  num_create > 0
AND    num_update > 0

输出

ID | SERVICE | FUNCTION
-: | :------ | :-------
 1 | 1234    | Create  
 3 | 1234    | Update  

db <>提琴here

答案 2 :(得分:0)

devise/registrations#create