SQL NOOB - Oracle连接和行号

时间:2016-04-19 15:00:39

标签: sql database oracle join

我希望得到一些关于我试图为Oracle数据库11g整理的SQL脚本的指导。

我正在尝试对“索赔”中的索赔进行处理。表,按年/月/和企业订购。

我能够获得索赔的数量,并按照我的意愿订购它们,但是我需要从另一个表格中提取数据,而且我在组合“row_number”时遇到了问题。带连接的功能。

到目前为止,这是我的脚本:

SELECT TO_CHAR (SYSTEM_ENTRY_DATE, 'YYYY') YEAR,
     TO_CHAR (SYSTEM_ENTRY_DATE, 'MM') MONTH,
     ENTERPRISE_IID,
     COUNT (*) CLAIMS
FROM (SELECT CLAIM.CLAIM_EID,
    CLAIM.SYSTEM_ENTRY_DATE,
    CLAIM.ENTERPRISE_IID,
    ROW_NUMBER () OVER (PARTITION BY CLAIM.CLAIM_EID, CLAIM.ENTERPRISE_IID
    ORDER BY CLAIM.SYSTEM_ENTRY_DATE DESC) RN
        FROM CLAIM
        WHERE CLAIM_IID IN (SELECT DISTINCT (CLAIM_IID)
            FROM CLAIM_LINE
            WHERE STATUS <> 'D')
            AND CLAIM.CONTEXT = '1'
            AND CLAIM.CLAIM_STATUS = 'A'
            AND CLAIM.LAST_ANALYSIS_DATE IS NOT NULL)
WHERE RN = 1
GROUP ENTERPRISE_IID,
TO_CHAR (SYSTEM_ENTRY_DATE, 'YYYY'),
TO_CHAR (SYSTEM_ENTRY_DATE, 'MM');

到目前为止,我的所有数据都来自于声明&#39;表。这得出以下结果:

YEAR MONTH ENTERPRISE_IID     CLAIMS
---- ----- -------------- ----------
2016 01                 6          1
2015 08                 6          3
2016 02                 6          2
2015 09                 6          2
2015 07                 6          2
2015 09                 5         22
2015 11                 5         29
2015 12                 5         27
2016 04                 5          8
2015 07                 5         29
2015 05                 5         15
2015 06                 5          5
2015 10                 5         45
2016 03                 5         54
2015 03                 5         10
2016 02                 5         70
2016 01                 5         55
2015 08                 5         32
2015 04                 5         12

19 rows selected.

enterprise_IID是&#39;企业的主要关键词。表。企业&#39;表格还包含&#39;名称&#39;每个条目的属性。我想加入声明和企业表,以显示此计数的企业名称,而不是enterprise_IID。

正如你所知道的那样,我对Oracle和SQL很陌生,而且我对这一点感到困惑。我在想我应该在两个表之间进行内连接,但是我不太确定在使用row_number函数时该怎么做。

或许我在这里采取了错误的做法,有人可能会把我推向另一个方向。

以下是我的尝试:

SELECT TO_CHAR (SYSTEM_ENTRY_DATE, 'YYYY') YEAR,
    TO_CHAR (SYSTEM_ENTRY_DATE, 'MM') MONTH,
    ENTERPRISE_IID,
    ENTERPRISE.NAME,
    COUNT (*) CLAIMS
FROM (SELECT CLAIM.CLAIM_EID,
    CLAIM.SYSTEM_ENTRY_DATE,
    CLAIM.ENTERPRISE_IID,
    ROW_NUMBER () OVER (PARTITION BY CLAIM.CLAIM_EID, CLAIM.ENTERPRISE_IID
    ORDER BY CLAIM.SYSTEM_ENTRY_DATE DESC) RN
        FROM CLAIM, enterprise
        INNER JOIN ENTERPRISE
        ON CLAIM.ENTERPRISE_IID = ENTERPRISE.ENTERPRISE_IID
        WHERE CLAIM_IID IN (SELECT DISTINCT (CLAIM_IID)
            FROM CLAIM_LINE
            WHERE STATUS <> 'D')
            AND CLAIM.CONTEXT = '1'
            AND CLAIM.CLAIM_STATUS = 'A'
            AND CLAIM.LAST_ANALYSIS_DATE IS NOT NULL)
WHERE RN = 1
GROUP BY ENTERPRISE.NAME,
ENTERPRISE_IID,
TO_CHAR (SYSTEM_ENTRY_DATE, 'YYYY'),
TO_CHAR (SYSTEM_ENTRY_DATE, 'MM');

提前谢谢!

&#34;期望的输出&#34;

YEAR MONTH NAME     CLAIMS
---- ----- ---- ----------
2016 01    Ent1        1
2015 08    Ent1        3
2016 02    Ent1        2
2015 09    Ent1        2
2015 07    Ent1        2
2015 09    Ent2       22
2015 11    Ent2       29
2015 12    Ent2       27
2016 04    Ent2        8
2015 07    Ent2       29
2015 05    Ent2       15
2015 06    Ent2        5
2015 10    Ent2       45
2016 03    Ent2       54
2015 03    Ent2       10
2016 02    Ent2       70
2016 01    Ent2       55
2015 08    Ent2       32
2015 04    Ent2       12

19 rows selected.

3 个答案:

答案 0 :(得分:2)

你可以试试这个。在使用row_number函数计算行号时可以使用连接。

SELECT TO_CHAR (SYSTEM_ENTRY_DATE, 'YYYY') YEAR,
    TO_CHAR (SYSTEM_ENTRY_DATE, 'MM') MONTH,
    ENTERPRISE_IID,
    NAME,
    COUNT (*) CLAIMS
FROM (SELECT CLAIM.CLAIM_EID,
      CLAIM.SYSTEM_ENTRY_DATE,
      CLAIM.ENTERPRISE_IID,
      ENTERPRISE.NAME,
      ROW_NUMBER () OVER (PARTITION BY CLAIM.CLAIM_EID, CLAIM.ENTERPRISE_IID
      ORDER BY CLAIM.SYSTEM_ENTRY_DATE DESC) RN
      FROM CLAIM --, enterprise (this is not required as the table is being joined already)
      INNER JOIN ENTERPRISE ON CLAIM.ENTERPRISE_IID = ENTERPRISE.ENTERPRISE_IID
      INNER JOIN (SELECT DISTINCT CLAIM_IID FROM CLAIM_LINE WHERE STATUS <> 'D') CLAIM_LINE 
      ON CLAIM.CLAIM_IID = CLAIM_LINE.CLAIM_IID
      WHERE CLAIM.CONTEXT = '1'
      AND CLAIM.CLAIM_STATUS = 'A'
      AND CLAIM.LAST_ANALYSIS_DATE IS NOT NULL) t
WHERE RN = 1
GROUP BY NAME, --ENTERPRISE.NAME (The alias ENTERPRISE is not accessible here.)
ENTERPRISE_IID,
TO_CHAR(SYSTEM_ENTRY_DATE, 'YYYY'),
TO_CHAR(SYSTEM_ENTRY_DATE, 'MM');

答案 1 :(得分:1)

只是假设开始,因为查询输出的要求不清楚:

  SELECT 
    C.ENTERPRISE_IID, 
    E.ENTERPRISE_NAME,
    extract(year from CLAIM.SYSTEM_ENTRY_DATE) SYSTEM_ENTRY_YEAR,
    extract(month from CLAIM.SYSTEM_ENTRY_DATE) SYSTEM_ENTRY_MONTH,
    count(distinct C.CLAIM_EID) CLAIM_COUNT
  FROM 
    CLAIM      C, 
    ENTERPRISE E
  WHERE 
    C.CLAIM_IID IN (
      SELECT DISTINCT (CLAIM_IID)
      FROM CLAIM_LINE
      WHERE STATUS <> 'D'
    )
    AND C.CONTEXT = '1'
    AND C.CLAIM_STATUS = 'A'
    AND C.LAST_ANALYSIS_DATE IS NOT NULL
    AND E.ENTERPRISE_IID = C.ENTERPRISE_IID
  GROUP BY
    C.ENTERPRISE_IID, 
    E.ENTERPRISE_NAME,
    extract(year from CLAIM.SYSTEM_ENTRY_DATE),
    extract(month from CLAIM.SYSTEM_ENTRY_DATE) 
  ORDER BY
    extract(year from CLAIM.SYSTEM_ENTRY_DATE),
    extract(month from CLAIM.SYSTEM_ENTRY_DATE), 
    E.ENTERPRISE_NAME

答案 2 :(得分:1)

我会写这样的查询:

SELECT TO_CHAR(TRUNC(c.system_entry_date,'MM'),'YYYY') AS year
     , TO_CHAR(TRUNC(c.system_entry_date,'MM'),'MM')   AS month
     , e.enterprise_name                               AS name 
     , COUNT(*)                                        AS claims
  FROM (
         SELECT r.claim_eid
              , r.enterprise_iid
              , MAX(r.system_entry_date) AS system_entry_date
           FROM ( SELECT DISTINCT l.claim_iid
                    FROM claim_line l
                   WHERE l.status <> 'D'
                ) d
           JOIN claim r
             ON r.claim_iid = d.claim_iid
            AND r.context = '1'
            AND r.claim_status = 'A'
            AND r.last_analysis_date IS NOT NULL
          GROUP
             BY r.claim_eid
              , r.enterprise_iid
       ) c
  JOIN enterprise e
    ON e.enterprise_iid = c.enterprise_iid
 GROUP
    BY c.enterprise_iid
     , TRUNC(c.system_entry_date,'MM')
     , e.enterprise_name
 ORDER
    BY e.enterprise_name
     , TRUNC(c.system_entry_date,'MM')

一些注意事项:

我更喜欢使用表名或短表别名限定所有列引用,并为所有内联视图指定别名。

由于ROW_NUMBER()的使用似乎是获取声明的“最新”system_entry_date并消除重复,我更倾向于使用GROUP BY和MAX()聚合。

我更喜欢使用连接操作而不是NOT IN(子查询)模式。 (或者,我倾向于使用NOT EXISTS(相关子查询)模式。

如果您使用TO_CHAR或EXTRACT,我认为这不重要。 TO_CHAR让你在本月获得领先的零,我认为EXTRACT(MONTH)不会让你成为领先的零。我会使用哪个让我最接近我需要的结果集。个人而言,我只返回一个列,包含年份和月份作为一个字符串,例如TO_CHAR(,'YYYYMM')或只是DATE值。这完全取决于我将要做的事情。