将表中的每个字段与同一表中的每个其他字段进行比较

时间:2017-06-29 17:44:03

标签: sql hive hiveql

想象一下只有一列的表格。

+------+
|  v   |
+------+
|0.1234|
|0.8923|
|0.5221|
+------+

我想对第K行执行以下操作:

  1. 行K = 1值:0.1234
  2. 计算表格其余部分中的值小于或等于第1行中的值。
  3. 遍历所有行 输出应该是:

    +------+-------+
    | v    |output |
    +------+-------+
    |0.1234|   0   |
    |0.8923|   2   | 
    |0.5221|   1   | 
    +------+-------+
    

    快速更新我正在使用这种方法计算上表中v的每个值的统计量。交叉连接方法对于我正在处理的数据大小来说太慢了。所以,我为v值网格计算了我的stat,然后将它们与原始数据中的vs匹配。 v_table是之前的数据表,stat_comp是统计表。

    AS SELECT t1.* 
    ,CASE WHEN v<=1.000000 THEN pr_1 
    WHEN v<=2.000000 AND v>1.000000 THEN pr_2 
    FROM v_table  AS t1 
    LEFT OUTER JOIN stat_comp AS t2
    

4 个答案:

答案 0 :(得分:0)

Windows功能在1999年被添加到ANSI / ISO SQL,并在2013年5月15日发布的0.11版本中被添加到Hive中。
您正在寻找的是排名高,的变体,在ANSI / ISO SQL:2011中看起来像这样 -

rank () over (order by v with ties high) - 1

Hive目前不支持with ties ...,但逻辑可以使用count(*) over (...)实现

select  v
       ,count(*) over (order by v) - 1 as rank_with_ties_high_implicit

from    mytable
;

select  v
       ,count(*) over 
        (
            order by v
            range between unbounded preceding and current row            
        )  - 1  as rank_with_ties_high_explicit

from    mytable
;

答案 1 :(得分:-1)

生成样本数据

select 0.1234 as v into #t
union all
select 0.8923
union all
select 0.5221

这是查询

;with ct as (
    select ROW_NUMBER() over (order by v) rn
    , v
    from #t ot
)
select distinct v, a.cnt
from ct ot
    outer apply (select count(*) cnt from ct where ct.rn <> ot.rn and v <= ot.v) a

答案 2 :(得分:-1)

看到你的编辑后,看起来你看起来确实可以使用笛卡尔积,即CROSS JOIN。我打电话给你的桌子foo,并将其作为bar加入了自己:

SELECT foo.v, COUNT(foo.v) - 1 AS output
FROM foo
CROSS JOIN foo bar
WHERE foo.v >= bar.v
GROUP BY foo.v;

Here's a fiddle.

此查询交叉连接列,以便返回列元素的每个排列(您可以通过删除SUMGROUP BY子句并将bar.v添加到列中来自行查看。 SELECT)。然后在foo.v >= bar.v时添加一个计数,产生最终结果。

答案 3 :(得分:-2)

您可以自己获取表格的完整笛卡尔积,并总结一个案例陈述:

select a.x
, sum(case when b.x < a.x then 1 else 0 end) as count_less_than_x
from (select distinct x from T) a
, T b
group by a.x

这将为表中的每个唯一值提供一行,其中包含非唯一行的计数,其值小于此值。

请注意,既没有join也没有where子句。在这种情况下,我们实际上想要那样。对于a的每一行,我们会将完整副本别名为b。然后我们可以检查每一个,看它是否小于a.x。如果是,我们在计数中加1。如果没有,我们只需添加0。