Как перевести скалярный подзапрос в условную функцию OLAP в SQL? - PullRequest
0 голосов
/ 09 марта 2019

Я использую Teradata 15.10.У меня есть таблица с двумя столбцами last_name и first_name.Для каждой строки мне нужно подсчитать, сколько других строк имеют одинаковые last_name и first_name, но с обратными значениями, и отобразить это количество (даже если оно равно 0).На данный момент я использую этот запрос:

SELECT LAST_NAME, 
       FIRST_NAME,
      (SELECT Count(*)
       FROM   myTable AS T1
       WHERE  T1.FIRST_NAME = T2.LAST_NAME
         AND  T1.LAST_NAME  = T2.FIRST_NAME) AS REVERSE_NAME_COUNT
FROM myTable AS T2

К сожалению, это не очень быстро, и у меня есть много других столбцов, где я делаю такой подсчет.Мне было интересно, есть ли способ перевести вышеупомянутый скалярный подзапрос в функцию OLAP, например:

SUM(CASE WHEN T1.FIRST_NAME = T2.LAST_NAME AND T1.LAST_NAME = T2.FIRST_NAME THEN 1 ELSE 0 END) OVER(ROWS UNBOUNDED PRECEDING)

Но из того, что я понимаю, нет способа получить доступ к значениям, которые в настоящее время обрабатываются в разделе.Есть ли другой способ написать свой подзапрос?

Пример ввода:

       FIRST_NAME        LAST_NAME
----------------------------------
           SYLVIE           BOUVET
         LUCIENNE             BRUN
           BOUVET           SYLVIE
         FRANCINE            CARON
             BRUN         LUCIENNE
             BRUN         LUCIENNE
            KEVIN         MACHETEL
             REMI        MINVIELLE
          QUENTIN        THUILLIER
        MINVIELLE             REMI

Пример желаемого вывода:

       FIRST_NAME        LAST_NAME  REVERSE_NAME_COUNT
------------------------------------------------------
           SYLVIE           BOUVET                   1
         LUCIENNE             BRUN                   2
           BOUVET           SYLVIE                   1
         FRANCINE            CARON                   0
             BRUN         LUCIENNE                   1
             BRUN         LUCIENNE                   1
            KEVIN         MACHETEL                   0
             REMI        MINVIELLE                   1
          QUENTIN        THUILLIER                   0
        MINVIELLE             REMI                   1 

Ответы [ 2 ]

2 голосов
/ 09 марта 2019

Вы говорите о скалярном подзапросе в Select?

SELECT
   last_name
  ,(
     SELECT Count(*)
     FROM   myTable AS T1
     WHERE  T1.FIRST_NAME = T2.LAST_NAME
   )
FROM myTable AS t2

Тогда вы правы, вы не можете переписать его как функцию OLAP.

Эти скалярные подзапросы, как правило, имеют плохую производительность, но вы можете переписать их, используя Outer Join:

SELECT
   t2.last_name
  ,t1.Cnt 
FROM myTable AS t2 
LEFT JOIN
 ( 
   SELECT first_name, Count(*) AS Cnt
   FROM myTable
   GROUP BY 1
 ) AS t1
ON T1.FIRST_NAME = T2.LAST_NAME
0 голосов
/ 14 марта 2019

Благодаря @dnoeth я нашел решение.

SELECT
   T2.first_name
   T2.last_name
  ,SUM(t1.Cnt) 
FROM myTable AS T2 
LEFT JOIN
 ( 
   SELECT first_name, last_name, Count(*) AS Cnt
   FROM myTable
   GROUP BY 1, 2
 ) AS T1
ON T1.first_name = T2.last_name
AND T1.last_name = T2.first_name
GROUP BY 1, 2
...