我有一个SQL广告约定表:
| id | ad1 | ad2 | ad3 |
| ----|--------| ------| -------|
| 1 |val_1 |NULL | NULL |
| 2 |val_2 |val_1 | NULL |
| 3 |val_3 |NULL | val_3 |
我想在 ad1,ad2,ad3 列中列出所有广告价值出现时间。查询将返回
| value | times |
| --------| ------|
| val_1 | 2 |
| val_2 | 1 |
| val_3 | 2 |
执行此操作的最佳方法是什么(以获得最佳性能)?
答案 0 :(得分:3)
在子查询中使用UNION ALL
select t.value, count(*)
from (
select ad1 value from ad_convention
union all
select ad2 value from ad_convention
union all
select ad3 value from ad_convention
) t
group by t.value
答案 1 :(得分:2)
为此,我非常喜欢横向连接:
select ad, count(*)
from t, lateral
(values (ad1), (ad2), (ad3)) v(ad)
where ad is not null
group by ad;
答案 2 :(得分:0)
您可以使用未嵌套的数组:
select t.val, count(*)
from ads a, unnest(array[a.ad1, a.ad2, a.ad3]) t(val)
where t.val is not null
group by t.val;
不确定是比UNION ALL
更快还是更慢