SQL:将宽 Table 转换为窄 Table
SQL: Convert a Wide Table to Narrow Table
我有一个 table,其中每一行都有一些布尔字段,如下所示:
user_id | USD | EUR | CAD | ....
1 | 1 | 1 | 0 | ....
2 | 0 | 1 | 1 | ....
我需要将它转换成这样:
user_id | currency
1 | USD
1 | EUR
2 | EUR
2 | CAD
我设法用很多 UNION(每种货币一个)构建了一个丑陋的 SQL,但我觉得这不是最好的方法。帮助任何人?
P.S。
此查询将在 AWS Athena 上执行,因此我担心成本问题,我希望为此找到最佳查询。
如果您的数据库支持横向连接和 values()
行构造函数,那么您可以:
select x.user_id, x.currency
from mytable t
cross join lateral (values(user_id, 'USD', usd), (user_id, 'EUR', eur), (user_id, 'CAD', cad)) x(user_id, currency, val)
where x.val= 1
有些数据库使用 cross apply
而不是 cross join lateral
来实现横向连接。
更适合table 的方法是union all
。这效率较低,因为它需要多次 table 扫描:
select user_id, 'USD'currency from mytable where usd = 1
union all select user_id, 'EUR' from mytable where eur = 1
union all select user_id, 'CAD' from mytable where cad = 1
我有一个 table,其中每一行都有一些布尔字段,如下所示:
user_id | USD | EUR | CAD | ....
1 | 1 | 1 | 0 | ....
2 | 0 | 1 | 1 | ....
我需要将它转换成这样:
user_id | currency
1 | USD
1 | EUR
2 | EUR
2 | CAD
我设法用很多 UNION(每种货币一个)构建了一个丑陋的 SQL,但我觉得这不是最好的方法。帮助任何人?
P.S。 此查询将在 AWS Athena 上执行,因此我担心成本问题,我希望为此找到最佳查询。
如果您的数据库支持横向连接和 values()
行构造函数,那么您可以:
select x.user_id, x.currency
from mytable t
cross join lateral (values(user_id, 'USD', usd), (user_id, 'EUR', eur), (user_id, 'CAD', cad)) x(user_id, currency, val)
where x.val= 1
有些数据库使用 cross apply
而不是 cross join lateral
来实现横向连接。
更适合table 的方法是union all
。这效率较低,因为它需要多次 table 扫描:
select user_id, 'USD'currency from mytable where usd = 1
union all select user_id, 'EUR' from mytable where eur = 1
union all select user_id, 'CAD' from mytable where cad = 1