根据第1个和最后一个条目返回2行

时间:2013-03-27 15:42:28

标签: sql teradata

我试图为每个USERID拉2行,第一行是最旧的日期(RSLVD_DTTM),第二行是最新的(RSLVD_DTTM)

这是我目前拥有的

USERID  VIRTUAL_PROFILE            LINE_STABILITY numb1  numb2     RSLVD_DTTM

USER1  STGR_al2_d7296-1184_u1088-256    STABLE  "7,296" "20,074"    12/06/2012  
USER1  STGR_al1_d12288-5056_u1088-256   STABLE  "12,284""21,700"    08/01/2013  
USER1  STGR_al1_d7296-1184_u1088-256    STABLE  "7,292" "21,479"    06/11/2012  
USER1  STGR_al1_d7296-1184_u1088-256    STABLE  "7,292" "20,365"    03/04/2012

这是我想要输出的一个例子。

USERID  VIRTUAL_PROFILE LINE_STABILITY_RATING    numb1    numb2     RSLVD_DTTM
USER1   STGR_al1_d7296-1184_u1088-256   STABLE  "7,292" "20,365"    03/04/2012  
USER1   STGR_al1_d12288-5056_u1088-256  STABLE  "12,284""21,700     08/01/2013

这是我的查询

select 
  USERID,
  VIRTUAL_PROFILE, 
  LINE_STABILITY_RATING,
  numb1,
  numb2,
  RSLVD_DTTM
from 
  symmktg.V_NDW_ACTUAL_SPEEDS, symmktg.VREMEDY_SYM_TICKET
where 
   USERID IS IN ('USER1')
   and cast(RSLVD_DTTM as date) = '2013/03/23' 

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:1)

您可以使用窗口函数row_number()

select USERID,VIRTUAL_PROFILE, LINE_STABILITY_RATING,numb1,numb2,RSLVD_DTTM
from (select USERID,VIRTUAL_PROFILE, LINE_STABILITY_RATING,numb1,numb2,RSLVD_DTTM,
             row_number() over (partition by userId order by rslvd_dttm asc) as seqnuma,
             row_number() over (partition by userId order by rslvd_dttm desc) as seqnumd
      from symmktg.V_NDW_ACTUAL_SPEEDS, symmktg.VREMEDY_SYM_TICKET
      where USERID IS IN ('USER1') and cast(RSLVD_DTTM as date) = '2013/03/23' 
     ) t
where seqnuma = 1 or seqnumd = 1

大多数数据库都支持此功能。

顺便说一下,我不明白你的查询。连接条件应该使用现代连接语法而不是,

答案 1 :(得分:1)

以下查询将仅获取给定用户的最旧和最新记录:

select userid,
       virtual_profile,
       line_stability_rating,
       numb1,
       numb2,
       rslvd_dttm
from 
   symmktg.v_ndw_actual_speeds, 
   symmktg.vremedy_sym_ticket

where 
   userid in ('user1')
   and (rslvd_dttm = (select min(rslvd_dttm) 
                      from symmktg.v_ndw_actual_speeds, symmktg.vremedy_sym_ticket
                      where userid in ('user1'))
    or  (rslvd_dttm = (select max(rslvd_dttm) 
                       from symmktg.v_ndw_actual_speeds, symmktg.vremedy_sym_ticket)
                       where userid in ('user1'))

答案 2 :(得分:0)

您的查询没有告诉我们您的表定义,即哪个列来自哪个表。

看起来你正在使用交叉连接,这意味着你得到的结果集与每个表的字段之间没有明确的关系。这可能是有意的,但我对此表示怀疑。我希望你的两个表之间有某种主/外键关系,这样对于一个表中的每一行,都有一些来自另一个表的相应行。目前,对于一个表中的每一行,您将从另一个表中返回每个行。

所以我认为这是你所使用的一般模式,使用更现代(并且明确清晰)的Ansi92语法:

  Select 
    t.your-return-values, 
    ..., 
    o.your-other-return-values, 
    ...

  From
    Sourcetable t

    Inner join yourothertable o 
    on o.somekey = t.somekey

    Inner join
    (
       Select UserId, min(rslvd_dttm) as mindttm, max(rsvld_dttm) as maxdttm
       From sourcetable
       Group by userid

    ) q
    On t.userid = q.userid 
    and (t.rslvd_dttm = q.mindttm or t.rslvd_dttm = q.maxdttm)

但是,您需要确定一个表中的哪个字段与另一个表中的哪个字段相关,我是为了指定第一个连接的键。

此外,连接当前是INNER,这意味着如果第二个表中至少存在一个相应的结果,它将仅返回第一个表的结果。

您可能希望将其更改为LEFT,这意味着返回包含第一个表中的值的行,即使找不到第二个表中的匹配行(在这种情况下,对于该行,这些列将返回null)。

如果您需要使用Ansi89语法,请告诉我,我会看到我能做什么!

答案 3 :(得分:0)

正如其他一些人已经告诉过你,两个表之间没有真正的连接条件。

添加到Gordon Linoff的解决方案:

  1. 您可以使用QUALIFY代替Teradata中的派生表
  2. 两个具有不同ORDER BY的ROW_NUMBER将导致两步计算,当您使用MAX / MIN重写它时,它只是一步
  3. 这将导致

    select 
      USERID,
      VIRTUAL_PROFILE, 
      LINE_STABILITY_RATING,
      numb1,
      numb2,
      RSLVD_DTTM
    from 
      symmktg.V_NDW_ACTUAL_SPEEDS, symmktg.VREMEDY_SYM_TICKET
    where 
       USERID IS IN ('USER1')
       and cast(RSLVD_DTTM as date) = '2013/03/23'
    qualify 
       min() over (partition by userId) = RSLVD_DTTM
    or max() over (partition by userId) = RSLVD_DTTM