【问题标题】:Get only top row from SQL Query仅从 SQL 查询中获取第一行
【发布时间】:2016-03-14 02:53:33
【问题描述】:

您好,我无法使用以下查询获取前 1 行。 它在oracle,plsql中。

SELECT per.person_no, 
       perbus.person_no, 
       perbus.edit_dt, 
       perbus.org_name, 
       perbus.FIRST_NAME 
FROM users.persons per
    LEFT OUTER JOIN (
        SELECT ASSOC.edit_dt,PER_CONTACTS.PERSON_NO, 
               PER_CONTACTS.PERSON_ID AS PER_ID,
               PER.EXTERNAL_PERSON_ID AS EXT_PER_ID,
               PER_CONTACTS.LNAME||', '||PER_CONTACTS.FNAME AS NAME, 
               PER_CONTACTS.FNAME AS FIRST_NAME, 
               PER_CONTACTS.MNAME AS MIDDLE_NAME, 
               PER_CONTACTS.LNAME AS LAST_NAME,
               ORG.ORG_NAME AS ORG_NAME,
               T_ORG.ORG_ID AS ORG_ID,
               T_ORG.ORG_DISPLAY_ID AS EXT_ORG_ID,
               rownum AS rn
        FROM USERS.PER_CONTACTS PER_CONTACTS
            LEFT OUTER JOIN USERS.PERSONS PER ON PER.PERSON_ID = PER_CONTACTS.PERSON_ID
            LEFT OUTER JOIN USERS.ASSOC ASSOC ON ASSOC.PERSON_ID = PER.PERSON_ID
            LEFT OUTER JOIN USERS.T_ORG T_ORG ON T_ORG.T_ORG_ID = ASSOC.T_ORG_ID
            LEFT OUTER JOIN USERS.ORG ORG ON ORG.ORG_ID = T_ORG.ORG_ID
        WHERE PER_CONTACTS.CONTACT_ROLE_LOV = 'EMPLOYEE' AND PER_CONTACTS.PERSON_NO IN (SELECT PERSON_NO FROM USERS.QA_APPROVED)
        ORDER BY ASSOC.edit_dt DESC
    ) 
    perbus ON perbus.PERSON_NO = PER.PERSON_NO 
WHERE PER.PERSON_NO IN (SELECT PERSON_NO FROM USERS.QA_APPROVED)

我是 oracle 新手,在上述查询中,由于数据的原因,我得到了重复项 - 我需要根据 Assoc.edit_dt 获取第一条记录。

我可以通过 Assoc.edit_dt 对记录进行排序,但是当我使用 where row_num = 1 inside the Join 之类的子句时,我的输出查询为空对于所有 perbus 表字段。

请指教。

【问题讨论】:

  • 你能显示你在哪里添加row_num = 1

标签: sql plsql oracle11g oracle-sqldeveloper plsqldeveloper


【解决方案1】:

试试这个

如果您想按 PERSON_NO 返回 TOP 1 行,那么

替换

rownum as rn

ROW_NUMBER() OVER (PARTITION BY PER_CONTACTS.PERSON_NO 
                    ORDER BY ASSOC.edit_dt DESC) RN

如果您想整体返回 TOP 1,那么

替换

rownum as rn

ROW_NUMBER() OVER (ORDER BY ASSOC.edit_dt DESC) RN

最后在您的外部 where 子句中,只需执行 RN = 1 即可选择前 1 行

WHERE PER.PERSON_NO IN (select PERSON_NO from USERS.QA_APPROVED) AND RN = 1

【讨论】:

    【解决方案2】:

    您可以使用结果偏移和获取第一个子句(仅适用于 12c)

    只需添加

    FETCH FIRST ROW ONLY;
    

    order by 子句之后

    了解更多信息。 read this

    希望这会有所帮助 =)

    编辑:

    SELECT per.person_no, 
           perbus.person_no, 
           perbus.edit_dt, 
           perbus.org_name, 
           perbus.FIRST_NAME 
    FROM users.persons per
        LEFT OUTER JOIN (
            SELECT ASSOC.edit_dt AS EDIT_DT,PER_CONTACTS.PERSON_NO, 
                   PER_CONTACTS.PERSON_ID AS PER_ID,
                   PER.EXTERNAL_PERSON_ID AS EXT_PER_ID,
                   PER_CONTACTS.LNAME||', '||PER_CONTACTS.FNAME AS NAME, 
                   PER_CONTACTS.FNAME AS FIRST_NAME, 
                   PER_CONTACTS.MNAME AS MIDDLE_NAME, 
                   PER_CONTACTS.LNAME AS LAST_NAME,
                   ORG.ORG_NAME AS ORG_NAME,
                   T_ORG.ORG_ID AS ORG_ID,
                   T_ORG.ORG_DISPLAY_ID AS EXT_ORG_ID,
                   rownum AS rn
            FROM USERS.PER_CONTACTS PER_CONTACTS
                LEFT OUTER JOIN USERS.PERSONS PER ON PER.PERSON_ID = PER_CONTACTS.PERSON_ID
                LEFT OUTER JOIN USERS.ASSOC ASSOC ON ASSOC.PERSON_ID = PER.PERSON_ID
                LEFT OUTER JOIN USERS.T_ORG T_ORG ON T_ORG.T_ORG_ID = ASSOC.T_ORG_ID
                LEFT OUTER JOIN USERS.ORG ORG ON ORG.ORG_ID = T_ORG.ORG_ID
            WHERE PER_CONTACTS.CONTACT_ROLE_LOV = 'EMPLOYEE' AND PER_CONTACTS.PERSON_NO IN (SELECT PERSON_NO FROM USERS.QA_APPROVED)
            --ORDER BY ASSOC.edit_dt DESC
        ) 
        perbus ON perbus.PERSON_NO = PER.PERSON_NO 
    WHERE PER.PERSON_NO IN (SELECT PERSON_NO FROM USERS.QA_APPROVED)
    ORDER BY perbus.edit_dt DESC 
    FETCH FIRST ROW ONLY;
    

    仅供参考,您为所有列提供了别名,除了一个,即 assoc.edit_dt 但您在主查询中调用它就好像它有一个别名一样。所以我采取了特权为 assoc.edit_dt

    添加别名

    【讨论】:

    • 给我错误,使用后订购时脚本未编译
    • 您能发布生成的错误吗?您是否在主查询中添加了 1(或任何列)的顺序,然后是我的答案?我编辑了您的查询,您可以试试吗?
    • 我注意到我使用的是 oracle 11。获取第一行在 11 中有效?
    【解决方案3】:

    这里使用解析函数肯定能解决你的问题。根据 person_id 和 Assoc_edt_dt 我们只能拉出一条具有最大/最小行的记录。以下是您可以尝试的sn-p。希望对您有所帮助

    SELECT per.person_no,
      perbus.person_no,
      perbus.edit_dt,
      perbus.org_name,
      perbus.FIRST_NAME
    FROM users.persons per
    LEFT OUTER JOIN
      (SELECT ASSOC.edit_dt,
        PER_CONTACTS.PERSON_NO,
        PER_CONTACTS.PERSON_ID AS PER_ID,
        PER.EXTERNAL_PERSON_ID AS EXT_PER_ID,
        PER_CONTACTS.LNAME
        ||', '
        ||PER_CONTACTS.FNAME AS NAME,
        PER_CONTACTS.FNAME   AS FIRST_NAME,
        PER_CONTACTS.MNAME   AS MIDDLE_NAME,
        PER_CONTACTS.LNAME   AS LAST_NAME,
        ORG.ORG_NAME         AS ORG_NAME,
        T_ORG.ORG_ID         AS ORG_ID,
        T_ORG.ORG_DISPLAY_ID AS EXT_ORG_ID,
        ROW_NUMBER() OVER(PARTITION BY PER_CONTACTS.PERSON_ID ORDER BY ASSOC.edit_dt DESC) rn
      FROM USERS.PER_CONTACTS PER_CONTACTS
      LEFT OUTER JOIN USERS.PERSONS PER
      ON PER.PERSON_ID = PER_CONTACTS.PERSON_ID
      LEFT OUTER JOIN USERS.ASSOC ASSOC
      ON ASSOC.PERSON_ID = PER.PERSON_ID
      LEFT OUTER JOIN USERS.T_ORG T_ORG
      ON T_ORG.T_ORG_ID = ASSOC.T_ORG_ID
      LEFT OUTER JOIN USERS.ORG ORG
      ON ORG.ORG_ID                       = T_ORG.ORG_ID
      WHERE PER_CONTACTS.CONTACT_ROLE_LOV = 'EMPLOYEE'
      AND PER_CONTACTS.PERSON_NO         IN
        (SELECT PERSON_NO FROM USERS.QA_APPROVED
        )
      ORDER BY ASSOC.edit_dt DESC
      ) perbus ON perbus.PERSON_NO = PER.PERSON_NO
    WHERE PER.PERSON_NO           IN
      (SELECT PERSON_NO FROM USERS.QA_APPROVED
      )
    AND perbus.rn = 1;
    

    【讨论】:

    • 我必须确保我的加入释放了一行。我不能在外面使用rownum
    【解决方案4】:

    要从数据集中仅获取“少数”记录,您可以使用“rownum” - 这是一个示例:

    select * from user_tables where rownum < 4
    

    另一个示例(根据“table_name”选择前 2 行):

    select * from (select * from user_tables order by table_name) where rownum<3
    

    注意:请勿使用等号 (=),而必须使用 ()。

    【讨论】:

    • 你可以使用“rownum = 1”来获取第一行。
    猜你喜欢
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 2019-08-13
    • 2018-01-29
    • 1970-01-01
    • 2021-10-07
    相关资源
    最近更新 更多