Лучший подход для получения данных для последней работы в Oracle - PullRequest
0 голосов
/ 03 июля 2018

У меня есть две таблицы, которыми я сейчас пользуюсь:

СТРАНЫ

ID  Name                       ShortName
1   France                     FR
2   United Kingdom             UK
3   United States Of America   USA
4   Argentina                  AG
5   Portugal                   PO
6   Spain                      SP
7   Italy                      IT

JOBDATA

JobID  CountryID TotalPercentage Indicator TimeStamp
500    1         78.9            NEW       10-06-2018
501    1         93.2            NEW       11-06-2018
509    1         91.11           NEW       02-07-2018
508    2         72.5            NEW       02-07-2018
502    2         88.57           NEW       12-06-2018
503    4         46.67           NEW       12-06-2018
506    4         91.43           NEW       29-06-2018
507    2         53.33           NEW       01-07-2018
504    1         50              NEW       14-06-2018
505    4         44.4            NEW       15-06-2018
501    1         0               OLD       11-06-2018
506    4         40              OLD       29-06-2018
508    2         78              OLD       02-07-2018

Я написал приведенный ниже запрос, чтобы вернуть мои данные следующим образом, т. Е. Только для отображения значений последних идентификаторов заданий для данной страны:

Select (Select Name from Country where ID = T1.CountryID) as CountryName , 
(Select ShortName from Country where ID = T1.CountryID) as CountryShortName , 
Coalesce(Round(T1.TotalPercentage,2),0) As TrueCount , 
(Case
  When Coalesce(Round(T1.TotalPercentage,2),0) = 0
  Then Coalesce(Round(T1.TotalPercentage,2),0)
  Else 100-Coalesce(Round(T1.TotalPercentage,2),0)
 End) As Falsecount
FROM JobData T1 LEFT OUTER JOIN JobData T2 
ON (T1.CountryId = T2.CountryId AND T1.JobId < T2.JobId)
WHERE T2.CountryId IS NULL AND Indicator = 'NEW'; 

1010 *
*

CountryName      CountryShortName  TrueCount  FalseCount
France           FR                91.11      8.89
United Kingdom   UK                72.5       27.5
Argentina        AG                91.43      8.57

Я понимаю, что правильно получаю вышеуказанный результат, но есть ли лучший подход и более быстрый способ получить желаемый результат?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Мне нравится CROSS APPLY для этого, потому что это позволяет вам использовать ORDER BY ... FETCH FIRST 1 ROW ONLY в соединении.

Следующий запрос предоставит вам каждую страну и самую последнюю NEW информацию о вакансиях для каждой страны. Затем вы можете дополнительно обработать результаты в соответствии с приведенными выше требованиями к вашему запросу, которые вы не объяснили, и я не потратил время на то, чтобы разобраться.

SELECT c.*, j.* 
FROM countries c 
CROSS APPLY ( SELECT * 
              FROM jobdata j2 
              WHERE j2.countryId = c.id 
              AND j2.indicator = 'NEW' 
              ORDER BY j2.timestmp DESC
              FETCH FIRST 1 ROW ONLY ) j

+----+----------------+-----------+-------+-----------+-----------------+-----------+-----------+
| ID |      NAME      | SHORTNAME | JOBID | COUNTRYID | TOTALPERCENTAGE | INDICATOR | TIMESTMP  |
+----+----------------+-----------+-------+-----------+-----------------+-----------+-----------+
|  1 | France         | FR        |   509 |         1 |           91.11 | NEW       | 02-JUL-18 |
|  2 | United Kingdom | UK        |   508 |         2 |            72.5 | NEW       | 02-JUL-18 |
|  4 | Argentina      | AG        |   506 |         4 |           91.43 | NEW       | 29-JUN-18 |
+----+----------------+-----------+-------+-----------+-----------------+-----------+-----------+
0 голосов
/ 03 июля 2018

Вы можете JOIN таблицу COUNTRY, чтобы избежать множественных запросов к этой таблице (Nrows * 2 столбца)

Другой подход - это аналитический запрос:

   SELECT CountryName
         , CountryShortName
         , TrueCount
         , Falsecount
    FROM   ( SELECT c.NAME                                    AS CountryName
                  , c.ShortName                               AS CountryShortName
                  , Coalesce(Round(T1.TotalPercentage,2),0) As TrueCount , 
                    (Case
                      When Coalesce(Round(T1.TotalPercentage,2),0) = 0
                      Then Coalesce(Round(T1.TotalPercentage,2),0)
                      Else 100-Coalesce(Round(T1.TotalPercentage,2),0)
                     End) As Falsecount
                  , ROW_NUMBER () OVER ( partition BY t1.CountryId ORDER BY T1.JobId DESC) rn
             FROM   JobData T1
             JOIN   Country c
               ON c.ID = T1.CountryID
             WHERE  t1.Indicator = 'NEW' ) t
    WHERE  rn = 1; 

Я предлагаю вам использовать самый простой для поддержки / понимания для вас, и требуется самый быстрый

http://sqlfiddle.com/#!4/f069dd/8

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...