如何获得解码/未透视行的唯一计数(列到行)

Posted

技术标签:

【中文标题】如何获得解码/未透视行的唯一计数(列到行)【英文标题】:How to get a unique count of decoded/unpivoted rows (column to row) 【发布时间】:2019-04-02 15:47:56 【问题描述】:

使用 Oracle 数据库。 将一组列转换为行并为每一行获取唯一计数时遇到问题。

我正在使用一个表格,该表格可识别附加到特定帐号的一组值(最多六个)。我想取消这六列,以便它们列在自己的行中。每行都有一个表示位置值的计数(即,值 1 = 1、值 3 = 3 等...)

例如,我有一个如下表。 每个帐号的值 (1-6) 始终是唯一的

AccountNumber|Value1|Value2|Value3|Value4|Value5|Value6
-------------------------------------------------------
1            |123   |1234  |12345 |12    |12345 |1234
2            |123   |1234  |12345 |12    |12345 |1234
3            |123   |1234  |12345 |12    |12345 |1234

我希望将优先顺序附加到值编号。

AccountNumber|Order|Value
-------------------------
1            |1    |123
1            |2    |1234
1            |3    |12345
1            |4    |12
1            |5    |123456
1            |6    |1
2            |1    |123
2            |2    |1234
2            |3    |12345
2            |4    |12
2            |5    |123456
2            |6    |1
3            |1    |123
3            |2    |1234
3            |3    |12345
3            |4    |12
3            |5    |123456
3            |6    |1

我有以下,

SELECT
'1' AS FACILITYID,
HL.ACCOUNT_ID AS AccountNumber,
--UNPIVOT_ROW,
DECODE(UNPIVOT_ROW, 1, TDL.DX_ONE_ID,
                    2, TDL.DX_TWO_ID,
                    3, TDL.DX_THREE_ID,
                    4, TDL.DX_FOUR_ID,
                    5, TDL.DX_FIVE_ID,
                    6, TDL.DX_SIX_ID) AS Value,

FROM ACCOUNT_LIST HL
INNER JOIN TRANSACTIONS TRAN ON HL.ACCOUNT_ID = TRAN.ACCOUNT_ID,
(SELECT LEVEL AS UNPIVOT_ROW FROM DUAL CONNECT BY LEVEL <= 6)

我能够取消透视(使用 DECODE(),UNPIVOT() 给我带来了问题),但我似乎无法将我的头脑围绕关联唯一计数。

这可能很容易,但它只是从我的脑海中滑出,试图在我取消旋转之前想一种有效的方法来处理 20,000 多行,而不会产生太多开销。

我尝试返回值 UNPIVOT_ROW 并使用第二次解码输出一个数字,但它只是不断吐出数字“1”

任何帮助或建议将不胜感激!

【问题讨论】:

您真的是指“计数” - 还是位置(级别/顺序,它们都是保留字......当然,计数也是如此)? 位置,所以你下面的解决方案看起来像我想做的。你可能是对的,我肯定是想多了。表格本身更复杂,但我想特别关注订单/位置。感谢您的示例,我将立即测试您的解决方案。 【参考方案1】:

我认为你过于复杂了,只需要一个基本的反透视操作:

select account_id as "AccountNumber", position as "Order", value as "Value" 
from (
  select 1 as facility_id, hl.account_id, tdl.dx_one_id, tdl.dx_two_id,
    tdl.dx_three_id, tdl.dx_four_id, tdl.dx_five_id, tdl.dx_six_id
  from account_list hl
  inner join transactions tdl on hl.account_id = tdl.account_id
)
unpivot (value for position in (dx_one_id as 1, dx_two_id as 2, dx_three_id as 3,
                                dx_four_id as 4, dx_five_id as 5, dx_six_id as 6))

带有与您的第一个示例匹配的起始数据的演示:

-- CTEs for sample data
with account_list (account_id) as (
            select 1 from dual
  union all select 2 from dual
  union all select 3 from dual
),
transactions (account_id, dx_one_id, dx_two_id, dx_three_id, dx_four_id, dx_five_id, dx_six_id) as (
            select 1, 123, 1234, 12345, 12, 12345, 1234 from dual
  union all select 2, 123, 1234, 12345, 12, 12345, 1234 from dual
  union all select 3, 123, 1234, 12345, 12, 12345, 1234 from dual
)
-- actual query
select account_id as "AccountNumber", position as "Order", value as "Value" 
from (
  select 1 as facility_id, hl.account_id, tdl.dx_one_id, tdl.dx_two_id,
    tdl.dx_three_id, tdl.dx_four_id, tdl.dx_five_id, tdl.dx_six_id
  from account_list hl
  inner join transactions tdl on hl.account_id = tdl.account_id
)
unpivot (value for position in (dx_one_id as 1, dx_two_id as 2, dx_three_id as 3,
                                dx_four_id as 4, dx_five_id as 5, dx_six_id as 6))
order by facility_id, account_id, position;

得到

AccountNumber      Order      Value
------------- ---------- ----------
            1          1        123
            1          2       1234
            1          3      12345
            1          4         12
            1          5      12345
            1          6       1234
            2          1        123
            2          2       1234
            2          3      12345
            2          4         12
            2          5      12345
            2          6       1234
            3          1        123
            3          2       1234
            3          3      12345
            3          4         12
            3          5      12345
            3          6       1234

18 rows selected. 

【讨论】:

以上是关于如何获得解码/未透视行的唯一计数(列到行)的主要内容,如果未能解决你的问题,请参考以下文章

透视/转置标题表到行

如何在具有过滤器的数据透视表(Excel for Mac)中获得不同的计数?

在 OBIEE 中将总计添加到数据透视表行的末尾

用于计算唯一值的简单数据透视表

将具有唯一值的列转置到行的 SQL 查询

多列,多表列到行 unpivot