n-й результат в терадате - PullRequest
1 голос
/ 09 июля 2010

Я пытаюсь создать SQL-запрос Teradata, который будет возвращать n -ю хронологическую дату посещения для каждого пользователя. Например.,

user  |  visit_date
---------------------
  a      1/1      
  b      1/10
  c      1/20
  a      1/3
  a      1/4
  b      1/5
  c      1/15
  b      1/9


> magic_query_for_Second_visit;
user  |  second
------------------
  a       1/3
  b       1/9
  c       1/20

Я попробовал что-то подобное ниже, но Teradata закричал, что «Упорядоченные аналитические функции не разрешены в предложении WHERE» Я немного потянул за волосы, но не добился большого прогресса. Кто-нибудь видел это?

select user,
  row_number() over (partition by user order by visit_date desc) as rnum

from visitstable
  where rnum = 2

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

 user |  visit_date | rnum
---------------------------
  a        1/1          1
  a        1/3          2
  a        1/4          3
  b        1/5          1
  b        1/9          2
  b        1/10         3 
  c        1/15         1
  c        1/20         2

Заранее спасибо за помощь!

Ответы [ 3 ]

1 голос
/ 09 июля 2010

О, боже упаси, я должен посмотреть в документации. К вашему сведению, похоже, что qualify позволяет указывать упорядоченные аналитические ограничения. Однако qualify не является ANSI, поэтому я все еще раздаю очки для портативного решения ...

Я могу сделать:

select user,
  row_number() over (partition by user order by visit_date desc) as rnum

from visitstable
qualify rnum=2

... и получите ...

user  |   visit_date  |  rnum
-----------------------------
  a        1/3            2
  b        1/9            2
  c        1/20           2

Добавьте в закладки! :)

1 голос
/ 09 июля 2010
SELECT 
    user

FROM 
    visitstable

QUALIFY ROW_NUMBER() OVER (
    PARTITION BY 
        user
    ORDER BY 
        visit_date DESC) = 2

Я вижу из вашего комментария, что вы не обязательно хотите полагаться на специфичные для Teradata QUALIFY. Ниже приводится своего рода портативное решение (так как многие РСУБД теперь поддерживают CTE), основанное на ответе другого главы:

WITH tmp (user, rnum) AS (
    SELECT 
        user, 
        ROW_NUMBER() OVER (
            PARTITION BY 
                user 
            ORDER BY 
                visit_date DESC) AS rnum 
    FROM 
        visitstable)
SELECT
    tmp.*
FROM 
    tmp
WHERE 
    tmp.rnum = 2
0 голосов
/ 09 июля 2010

Какую версию SQL вы используете?Это похоже на более позднюю версию MS SQL Server, поэтому попробуйте использовать «общее табличное выражение», подобное этому ...

with cte as ( select user, row_number() over (partition by user order by visit_date desc) as rnum from visitstable )</p> <p>select * from cte where rnum = 2

Синтаксис может потребовать небольшой доработки, но этогенеральный директор.

...