Оракул-запрос для получения 20 лучших агентств, которые выпустили пропуск - PullRequest
0 голосов
/ 26 октября 2019

У меня есть запрос, который показывает дату, выданную агентством. Я хотел получить 20 лучших агентств, которые получили большинство пропусков, вот мой запрос

SELECT
eofficeuat.gatepass.agent_id,
eofficeuat.cnf_agents.agent_name,
to_char(eofficeuat.gatepass.issuedatetime, 'dd-mm-yyyy HH12:MI:SS PM') AS 
issueddatetime,
eofficeuat.gatepass.id AS passnumber,
eofficeuat.gatepass.vehicletype,
eofficeuat.cardprintlog_user.cardnumber
FROM
eofficeuat.gatepass
INNER JOIN eofficeuat.cnf_agents ON eofficeuat.gatepass.agent_id = eofficeuat.cnf_agents.agent_id
INNER JOIN eofficeuat.cardprintlog_user ON eofficeuat.gatepass.agent_id = eofficeuat.cardprintlog_user.agent_id
WHERE

eofficeuat.gatepass.issuedatetime between TO_DATE ('2019/09/28', 'yyyy/mm/dd') and TO_DATE ('2019/09/29', 'yyyy/mm/dd')
ORDER BY
eofficeuat.gatepass.issuedatetime

Ответы [ 2 ]

1 голос
/ 26 октября 2019

Ничто в ваших данных не идентифицирует "агентство". Если я предполагаю, что вы имеете в виду «агент», вы можете получить 20 лучших, агрегируя и затем ограничивая результат. В Oracle 12C + вы можете использовать:

SELECT gp.agent_id, a.agent_name, COUNT(*)
FROM eofficeuat.gatepass gp INNER JOIN 
     eofficeuat.cnf_agents a
     ON gp.agent_id = a.agent_id INNER JOIN
     eofficeuat.cardprintlog_user u
     ON gp.agent_id = u.agent_id
WHERE gp.issuedatetime BETWEN DATE '2019-09-28' AND DATE '2019-09-29'
GROUP BY gp.agent_id, a.agent_name
ORDER BY COUNT(*) DESC
FETCH FIRST 1 ROW ONLY;

В более ранних версиях необходим подзапрос:

SELECT *
FROM (SELECT gp.agent_id, a.agent_name, COUNT(*)
      FROM eofficeuat.gatepass gp INNER JOIN 
           eofficeuat.cnf_agents a
           ON gp.agent_id = a.agent_id INNER JOIN
           eofficeuat.cardprintlog_user u
           ON gp.agent_id = u.agent_id
      WHERE gp.issuedatetime BETWEEN DATE '2019-09-28' AND DATE '2019-09-29'
      GROUP BY gp.agent_id, a.agent_name
      ORDER BY COUNT(*) DESC
     ) a
WHERE rownum <= 20;

Очевидно, если вы имеете в виду «агентство», и это определяется различнымистолбцы, вы просто изменили бы предложения SELECT и GROUP BY.

Кроме того, я бы посоветовал вам никогда использовать BETWEEN для дат в Oracle. Существует компонент времени, который может вызывать проблемы.

Если вы намерены использовать только 2019-09-28, тогда:

gp.issuedatetime >= DATE '2019-09-28' AND
gp.issuedatetime < DATE '2019-09-29'

Если вы намереваетесь оба 28 и 29:

gp.issuedatetime >= DATE '2019-09-28' AND
gp.issuedatetime < DATE '2019-09-30'
0 голосов
/ 26 октября 2019

Вы можете использовать предложение LIMIT (версия 12c или выше) с TOP 20 записями следующим образом:

SELECT eofficeuat.gatepass.agent_id, eofficeuat.cnf_agents.agent_name, COUNT(1) as cnt
FROM eofficeuat.gatepass INNER JOIN 
     eofficeuat.cnf_agents
     ON eofficeuat.gatepass.agent_id = eofficeuat.cnf_agents.agent_id INNER JOIN
     eofficeuat.cardprintlog_user
     ON eofficeuat.gatepass.agent_id = eofficeuat.cardprintlog_user.agent_id
WHERE eofficeuat.gatepass.issuedatetime BETWEN DATE '2019-09-28' AND DATE '2019-09-29'
GROUP BY eofficeuat.gatepass.agent_id, eofficeuat.cnf_agents.agent_name
ORDER BY cnt DESC
FETCH FIRST 20 ROWS ONLY; -- this will fetch top 20 agents

Cheers !!

...