Sql 查找表中符合条件的最右边的列
我用Postgres创建了一个表,它统计电子邮件地址在层次结构的每个级别中出现的次数。层次结构的层次从左到右依次为:aka,区域汇总到品牌,区域汇总到区域,站点汇总到区域 我的目标是用电子邮件地址不同的最低层次结构级别的名称填充“Lower_distinct_level”列。下面是一个示例表:Sql 查找表中符合条件的最右边的列,sql,postgresql,Sql,Postgresql,我用Postgres创建了一个表,它统计电子邮件地址在层次结构的每个级别中出现的次数。层次结构的层次从左到右依次为:aka,区域汇总到品牌,区域汇总到区域,站点汇总到区域 我的目标是用电子邮件地址不同的最低层次结构级别的名称填充“Lower_distinct_level”列。下面是一个示例表: email_address | brand | region | area | site | lowest_distinct_level ----------------|-------|------
email_address | brand | region | area | site | lowest_distinct_level
----------------|-------|--------|------|------|----------------------
alpha@gmail.com | 1 | 1 | 1 | 2 |
beta@gmail.com | 1 | 1 | 2 | 0 |
gamma@gmail.com | 1 | 1 | 2 | 2 |
zeta@gmail.com | 1 | 2 | 0 | 0 |
- Alpha的电子邮件显示在两个站点中,但只有一个区域,所以最低级别应该用“区域”填充
- Beta的电子邮件显示在两个区域,但只有一个区域,所以“区域”应该填充
- Gamma的电子邮件出现在两个站点上,但这两个站点位于不同的区域。因此,“区域”应该被填充
- 泽塔的一行应该是“品牌”
简而言之,对于每一行,我需要找到值为1的最右边的列,并将该列的名称作为值输出到最低的_distinct_级别。是否有一种相对有效的方法来使用PLPGSQL或阵列来实现这一点?一般来说,我不太擅长编写脚本或编码,因此如果这是一件小事,我深表歉意。这是一个使用嵌套大小写的基本解决方案:
select email_address, brand, region, area, site,
case when site = 1 then 'site'
else case when area = 1 then 'area'
else case when region = 1 then 'region'
else case when brand = 1 then 'brand'
else ''
end
end
end
end as lowest_distinct_level
from mm;
结果是:
+-----------------+-------+--------+------+------+-----------------------+
| email_address | brand | region | area | site | lowest_distinct_level |
+-----------------+-------+--------+------+------+-----------------------+
| alpha@gmail.com | 1 | 1 | 1 | 2 | area |
+-----------------+-------+--------+------+------+-----------------------+
| beta@gmail.com | 1 | 1 | 2 | 0 | region |
+-----------------+-------+--------+------+------+-----------------------+
| gamma@gmail.com | 1 | 1 | 2 | 2 | region |
+-----------------+-------+--------+------+------+-----------------------+
| zeta@gmail.com | 1 | 2 | 0 | 0 | brand |
+-----------------+-------+--------+------+------+-----------------------+
Abelisto写了一个简短的版本:
select email_address, brand, region, area, site,
case when site = 1 then 'site'
when area = 1 then 'area'
when region = 1 then 'region'
when brand = 1 then 'brand'
else ''
end as lowest_distinct_level
from mm;
选中此处:这是使用嵌套大小写的基本解决方案:
select email_address, brand, region, area, site,
case when site = 1 then 'site'
else case when area = 1 then 'area'
else case when region = 1 then 'region'
else case when brand = 1 then 'brand'
else ''
end
end
end
end as lowest_distinct_level
from mm;
结果是:
+-----------------+-------+--------+------+------+-----------------------+
| email_address | brand | region | area | site | lowest_distinct_level |
+-----------------+-------+--------+------+------+-----------------------+
| alpha@gmail.com | 1 | 1 | 1 | 2 | area |
+-----------------+-------+--------+------+------+-----------------------+
| beta@gmail.com | 1 | 1 | 2 | 0 | region |
+-----------------+-------+--------+------+------+-----------------------+
| gamma@gmail.com | 1 | 1 | 2 | 2 | region |
+-----------------+-------+--------+------+------+-----------------------+
| zeta@gmail.com | 1 | 2 | 0 | 0 | brand |
+-----------------+-------+--------+------+------+-----------------------+
Abelisto写了一个简短的版本:
select email_address, brand, region, area, site,
case when site = 1 then 'site'
when area = 1 then 'area'
when region = 1 then 'region'
when brand = 1 then 'brand'
else ''
end as lowest_distinct_level
from mm;
检查这里:这确实可以用数组解决:
select *,
case array_position(array[site,area,region,brand],1)
when 1 then 'site'
when 2 then 'area'
when 3 then 'region'
else 'brand'
end as lowest_distinct_level
from mm
这确实可以通过一个数组来解决:
select *,
case array_position(array[site,area,region,brand],1)
when 1 then 'site'
when 2 then 'area'
when 3 then 'region'
else 'brand'
end as lowest_distinct_level
from mm
为什么您认为您需要一个存储函数?使用数组,它可以是
select…,(数组['site','area','region','brand'])[array\u position(数组[site,area,region,brand],1)],作为与…不同的最低级别。
如果行是1 2 1怎么办?您希望返回什么?您好,Gordon,由于层次结构文件的构造方式,无法返回1 2 1-一个站点不可能绑定到两个单独的区域。您认为为什么需要存储函数?使用数组,它可以是select…,(数组['site','area','region','brand'])[array_position(数组[site,area,region,brand],1)作为与…不同的最低级别
如果行为1 2 1怎么办?你想要返回什么?嗨,Gordon,由于层次结构文件是如何构造的,所以无法返回1-一个站点不可能绑定到两个单独的区域。谢谢你的快速回答。我显然在运行一个旧版本的Postgres。。。我不知道数组位置是一个东西,因为它显然是在9.5中添加的,而我的计算机有9.3。我将安装9.6并尝试您编写的内容。对我来说,更大的挑战是使这个通用-适用于任何数量的层次结构字段。谢谢你的快速回答。我显然在运行一个旧版本的Postgres。。。我不知道数组位置是一个东西,因为它显然是在9.5中添加的,而我的计算机有9.3。我将安装9.6并尝试您编写的内容。对我来说,更大的挑战是使这个通用-适用于任何数量的层次结构字段。谢谢@McNets!这个案例陈述非常有效。我应该在主要问题中写下这一点,但要更详细地说明我在做什么——最终目标是以一种通用的方式,针对任意数量的层次结构列(和名称)。我想我可以构建一个函数,通过根据传入的参数生成更新脚本来动态工作。@flamewheel使用array_position和查找表,您可以轻松获得它。显然,我不能使用array_position-在另一条注释中解释了这一点,但服务器上运行的Postgres版本是9.3.9。数组_位置看起来像是在9.5中添加的。由于我不是DBA,我现在无法升级:(谢谢@McNets!case语句工作得很好。我应该在主要问题中写下这一点,但要更详细地说明我在做什么-最终目标是使这项工作以通用方式进行,适用于任意数量的层次结构列(和名称)。我想我可以构建一个函数,通过根据传入的参数生成更新脚本来动态工作。@flamewheel使用array_position和一个查找表,您可以轻松获得它。显然,我不能使用array_position-在另一个注释中解释了这一点,但服务器上运行的Postgres版本是9.3.9.array_的职位看起来像是在9.5中添加的。由于我不是DBA,所以目前无法升级:(