返回值基于sql中的行组

问题描述 投票:0回答:3

我有以下数据

vid   prod
1001  other
1001  other
1001  fixed
1001  fixed
1001  other
1001  fixed
1002  other
1002  mobile
1002  mobile
1002  other
1003  other
1003  fixed
1003  other
1003  mobile
1004  fixed
1004  fixed
1005  mobile
1005  mobile

要求的输出

vid   prod    prod_2
1001  other   fixed
1001  other   fixed
1001  fixed   fixed
1001  fixed   fixed
1001  other   fixed
1001  fixed   fixed
1002  other   mobile
1002  mobile  mobile
1002  mobile  mobile
1002  other   mobile
1003  other   fixed_mobile
1003  fixed   fixed_mobile
1003  other   fixed_mobile
1003  mobile  fixed_mobile
1004  fixed   fixed
1004  fixed   fixed
1005  mobile  mobile
1005  mobile  mobile

基本上我必须编写查询来创建新列'prod_2',其中固定的和每行应该更新为固定的,如果移动和其他它应该是移动的,如果是固定的,移动的和其他它应该是fixed_mobile

sql vertica
3个回答
0
投票

我认为你必须根据条件使用联合

select vid,prod,'fixed' as prod2 from t1 where
  t1.vid in(
     select vid from t1     
      where prod in ('fixed','other')
      and vid not in
      (select vid from t1     
      where prod in ('fixed','mobile','other')
      having count(distinct prod )>=3
      group by vid
      )
      having count(distinct prod )>=2
      group by vid
     ) 
union all

select vid,prod,'mobile' as prod2 from t1 where
  t1.vid in(
     select vid from t1     
      where prod in ('mobile','other')
      having count(distinct prod )>=2
      group by vid
     ) 
union all
select vid,prod,'fixed_mobile' as prod2 from t1 where
  t1.vid in(
     select vid from t1     
      where prod in ('fixed','mobile','other')
       and vid not in
       (
        select vid from t1     
      where prod in ('fixed','other')
      having count(distinct prod )>=2
      group by vid
       )
      having count(distinct prod )>=3
      group by vid
     )

0
投票

因此,在prod_2中,您需要:

  • 'fixed_mobile'如果给定的vid存在“固定”和“移动”
  • 对于给定的视频,如果“固定”但不存在“移动”,则“固定”
  • 对于给定的视频,如果“移动”但不是“固定”,则为“移动”
  • 在任何其他情况下,“我想,两者都不是”,因为这也可能发生。

我将使用由vid分组的子查询,为每个vid返回每个相关产品的存在标志。 True大于False,因此布尔值的MAX()将告诉我们是否存在任何搜索值。然后,将主表与该子查询连接,并评估获取的标志以生成prod_2的字符串。

与此查询一样(第一个公用表表达式是您的输入,从WITH子句中的第二个公用表表达式开始。)

WITH 
-- this is your input, don't use it in final query                                                                                                                                                                                                  
input(vid,prod) AS (
          SELECT 1001,'other'
UNION ALL SELECT 1001,'other'
UNION ALL SELECT 1001,'fixed'
UNION ALL SELECT 1001,'fixed'
UNION ALL SELECT 1001,'other'
UNION ALL SELECT 1001,'fixed'
UNION ALL SELECT 1002,'other'
UNION ALL SELECT 1002,'mobile'
UNION ALL SELECT 1002,'mobile'
UNION ALL SELECT 1002,'other'
UNION ALL SELECT 1003,'other'
UNION ALL SELECT 1003,'fixed'
UNION ALL SELECT 1003,'other'
UNION ALL SELECT 1003,'mobile'
UNION ALL SELECT 1004,'fixed'
UNION ALL SELECT 1004,'fixed'
UNION ALL SELECT 1005,'mobile'
UNION ALL SELECT 1005,'mobile'
)
,
-- start your real WITH clause here ...
existance AS (
SELECT
  vid
, MAX(prod = 'fixed' ) AS fixed_exists
, MAX(prod = 'mobile') AS mobile_exists
FROM input
GROUP BY vid
)
SELECT 
  i.*
, CASE 
     WHEN fixed_exists AND mobile_exists THEN 'fixed_mobile'
     WHEN fixed_exists                   THEN 'fixed'
     WHEN mobile_exists                  THEN 'mobile'
     ELSE                                'none of both'
  END as prod_2
FROM input i
JOIN existance ex USING(vid)
ORDER BY i.vid
;

这就是你得到的:

vid  |prod  |prod_2
1,001|other |fixed
1,001|other |fixed
1,001|fixed |fixed
1,001|other |fixed
1,001|fixed |fixed
1,001|fixed |fixed
1,002|mobile|mobile
1,002|other |mobile
1,002|other |mobile
1,002|mobile|mobile 
1,003|mobile|fixed_mobile
1,003|other |fixed_mobile
1,003|other |fixed_mobile
1,003|fixed |fixed_mobile
1,004|fixed |fixed
1,004|fixed |fixed
1,005|mobile|mobile
1,005|mobile|mobile

快乐的玩......


0
投票

我使用LAG()在Vertica中使用临时表完成此操作。

CREATE LOCAL TEMPORARY TABLE IF NOT EXISTS table1
   (
      vid int
      ,prod varchar
   )
   ON COMMIT PRESERVE ROWS;

将您的(vid,prod)数据插入此表。

创建第二个临时表,为LAG()数据添加一列

CREATE LOCAL TEMPORARY TABLE IF NOT EXISTS table2
   (
      vid int
      ,prod varchar
      ,prod2 varchar
   )
   ON COMMIT PRESERVE ROWS;

INSERT INTO table2
SELECT vid, prod, 
LAG(prod, 1, 0) OVER 
(PARTITION BY vid ORDER BY vid) as prod2
FROM table1
GROUP BY vid, prod
HAVING COUNT(vid) > 1
ORDER BY vid

表2现在具有同一行上的所有组合。

vid     prod    prod2
1001    fixed   other
1001    other   0
1002    mobile  other
1002    other   0
1003    other   0
1004    fixed   0
1005    mobile  0

你可以使用案例逻辑限制结果(我的逻辑可能有点偏离这里)

   SELECT vid, prod, prod2,  
   CASE WHEN (((prod = 'mobile') AND (prod2 = 'fixed')) OR ((prod = 'fixed')  AND (prod2 = 'mobile'))) THEN 'fixed_mobile'
        WHEN ((prod = 'fixed'   OR   prod2 != 'mobile') OR (prod != 'mobile' AND prod2 != 'fixed')) THEN 'fixed'
        WHEN ((prod != 'fixed'   OR   prod2 = 'mobile') OR (prod = 'mobile' AND prod2 != 'fixed')) THEN 'mobile'
        ELSE 'none'
        END AS prod2
        FROM(SELECT vid, prod, prod2
     FROM table2 WHERE prod2 != '0') s1

结果:

vid     prod    prod2
1002    mobile  mobile
1001    fixed   none

最后,您可以将此数据插入另一个表(table3),只需执行一个简单的连接即可显示结果:

   SELECT t1.vid, t1.prod, t2.prod3
   FROM table1 t1
   left join table3 t2
   on t2.vid = t1.vid

显然,你可以单独使用子查询来完成相同的结果,但这看起来有点清晰。如下所示,在某些情况下,您有两个不同的vid案例评估为真。例如,vid=1003fixedmobileother

vid     prod    prod3
1001    fixed   fixed
1001    fixed   fixed
1001    fixed   fixed
1001    other   fixed
1001    other   fixed
1001    other   fixed
1002    mobile  fixed
1002    mobile  fixed
1002    other   fixed
1002    other   fixed
1003    fixed   fixed
1003    fixed   fixed_mobile
1003    fixed   fixed
1003    fixed   fixed_mobile
1003    mobile  fixed
1003    mobile  fixed_mobile
1003    mobile  fixed
1003    mobile  fixed_mobile
1003    other   fixed
1003    other   fixed_mobile
1003    other   fixed
1003    other   fixed_mobile
1004    fixed   (null)
1004    fixed   (null)
1005    mobile  (null)
1005    mobile  (null)
© www.soinside.com 2019 - 2024. All rights reserved.