将两行放在Oracle的同一行中

时间:2016-10-28 15:23:56

标签: sql oracle

我们以此表为例,它将产品与数字相关联 他从顾客的反馈中得到的明星(它恰好按星数排序):

| ProductID |  Stars  | 
|-----------|---------|
|    23     |    10   |
|    12     |    10   |
|    17     |     9   |
|     5     |     8   |
|    20     |     8   |
|    18     |     7   |  

如何选择(在同一行上显示)产品的ID 成对?

像这样:

|  Product1 |   Product2  | 
|-----------|-------------|
|    23     |      12     |
|    17     |       5     |
|    20     |      18     |  

或者像这样:

|     Products     | 
|------------------|
|    23     12     |
|    17      5     |
|    20     18     |

4 个答案:

答案 0 :(得分:0)

目前尚不清楚为什么在你的输出中你在20之前选择了5;请记住,表中的行不是ORDERED。在我的解决方案中,我通过明星然后通过productid订购;如果你的行也按其他东西排序,你可以改用它。

如果要一次对7个值进行分组,则可以将分区中的2更改为2。

这只是为了表明这可以在Oracle SQL中完成(在数据库中)。它不应该,但那是你的决定。

with
     inputs ( productid, stars) as ( 
       select 23, 10 from dual union all
       select 12, 10 from dual union all
       select 17,  9 from dual union all
       select  5,  8 from dual union all
       select 20,  8 from dual union all
       select 18,  7 from dual
     )
-- end of test data, solution begins below
select listagg(productid, ' ') within group (order by rn) as result
from ( select productid, stars,
              row_number() over (order by stars desc, productid desc) as rn
       from   inputs
     )
group by ceil(rn/2)
order by ceil(rn/2)
;

RESULT
------
23 12
17 20
5 18

答案 1 :(得分:0)

WITH t
     AS (SELECT 23 product_id, 10 stars FROM DUAL
         UNION ALL
         SELECT 12, 10 FROM DUAL
         UNION ALL
         SELECT 17, 9 FROM DUAL
         UNION ALL
         SELECT 5, 8 FROM DUAL
         UNION ALL
         SELECT 20, 8 FROM DUAL
         UNION ALL
         SELECT 18, 7 FROM DUAL),
     t2
     AS (  SELECT product_id,
                  stars,
                    ROW_NUMBER () OVER (ORDER BY stars DESC)
                  + MOD (ROW_NUMBER () OVER (ORDER BY stars DESC), 2)
                     grp
             FROM t
         ORDER BY stars DESC)
  SELECT LISTAGG (product_id, ' ') WITHIN GROUP (ORDER BY stars DESC, ROWNUM)
            AS product_id
    FROM t2
GROUP BY grp

结果

23 12
17 5
20 18

答案 2 :(得分:-1)

使用listagg生成option2

select stars, listagg(ProductID, ' ') within group (order by ProductID) as Products
from Table1
group by Stars

答案 3 :(得分:-1)

在oracle上,你可以使用一个函数调用listagg,它有点像C#(和其他语言)的加入。为了它的工作,你需要有一些东西来分组购买 - 似乎你想要彼此分组按列排序。首先为列创建行号,然后按div 2

进行分组

所以

SELECT LISTAGG(ProductID, ' ') WITHIN GROUP (ORDER BY ProductID) AS ProductList
FROM (
  SELECT ProductID, FLOOR((ROW_NUMBER() OVER (ORDER BY Stars)+1)/2) as GroupByMe FROM Table
) X
GROUP BY GroupByMe

如果你想每3次做一次,只需要/ 3次。

更有趣(因为更多人希望看到它)正在为每个数量的星星获取一个列表,如下所示:

SELECT Stars as StarCount, LISTAGG(ProductID, ' ') WITHIN GROUP (ORDER BY ProductID) As ProductList
FROM Table
GROUP BY Stars

当然这看起来像先前的答案,因为这是人们期望你想要的。