Get only top row from SQL Query

我的梦境 提交于 2019-12-08 09:45:37

问题


Hello I'm having trouble with getting the Top 1 row using the below query. its in 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)

I'm new to oracle and in the above query i'm getting duplicates because of the data - and i need to get the first record based on the Assoc.edit_dt.

I'm able to order the record by Assoc.edit_dt, but when i use a clause like where row_num = 1 inside the Join, my output query is null for all perbus table fields.

Please advise.


回答1:


Try this

If you want to return TOP 1 row by PERSON_NO then

replace

rownum as rn

with

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

If you want to return TOP 1 overall then

replace

rownum as rn

with

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

Finally in your outer where clause just do RN = 1 to pick top 1 row

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



回答2:


Here using analytical function will definitely resolve your issue.Based on the person_id and Assoc_edt_dt we can pull out only one record having max/min row. Below is snippet which you can try. Hope it helps

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;



回答3:


To fetch just "few" records from a dataset you can user "rownum" - here is an example:

select * from user_tables where rownum < 4

Another example (select first 2 rows based on "table_name):

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

Note: do not use equality (=) sign you must use (<) for this.




回答4:


You can use Result offset and fetch first clauses (only works on 12c)

just add

FETCH FIRST ROW ONLY;

after the order by clause

For more info. read this

Hope this helps =)

EDIT:

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;

FYI, you gave all the columns their aliases except for one and that is assoc.edit_dt but you are calling it in the main query as if it has an alias.So i took the previlige to add the alias for assoc.edit_dt



来源:https://stackoverflow.com/questions/34168550/get-only-top-row-from-sql-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!