如何从一列的不同行中获取值以分隔列
Posted
技术标签:
【中文标题】如何从一列的不同行中获取值以分隔列【英文标题】:How to get values from different rows from one column to separate columns 【发布时间】:2021-07-13 22:53:35 【问题描述】:我有一张这样的桌子:
app_id | service_name | result |
---|---|---|
100 | service_1 | res_json |
100 | service_2 | res_json |
100 | service_3 | res_json |
101 | service_1 | res_json |
101 | service_2 | res_json |
101 | service_3 | res_json |
我需要编写一个 SQL Server 查询,为一行中的每个 app_id 返回服务 1 和 2(但不是 3)的结果。期望的结果如下所示:
app_id | service_1_res | service_2_res |
---|---|---|
100 | res_json | res_json |
101 | res_json | res_json |
我尽最大努力为每个 app_id 返回结果两次(我猜是因为 where 子句,因为我为每个 app_id 选择了两行)。
select
t.application_id,
ts1.result as service_1_res,
ts2.result as service_2_res
from mytable t
left join mytable ts1 on t.app_id = ts1.app_id and ts1.service_name = 'service_1'
left join mytable ts2 on t.app_id = ts2.app_id and ts2.service_name = 'service_2'
where t.service_name in ('service_1', 'service_2')
我明白了:
app_id | service_1_res | service_2_res |
---|---|---|
100 | res_json | res_json |
100 | res_json | res_json |
101 | res_json | res_json |
101 | res_json | res_json |
可能某种嵌套查询会有所帮助。
【问题讨论】:
查找 PIVOT。这应该可以帮助你 【参考方案1】:create table mytable (
app_id int,
service_name varchar(50),
result varchar(50)
)
insert mytable
values
(100, 'service_1', 'res_json')
, (100, 'service_2', 'res_json')
, (100, 'service_3', 'res_json')
, (101, 'service_1', 'res_json')
, (101, 'service_2', 'res_json')
, (101, 'service_3', 'res_json')
select app_id
, min(case
when service_name = 'service_1' then result
end) as service_1
, min(case
when service_name = 'service_2' then result
end) as service_2
from mytable
group by app_id
https://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=9b97c6d2a38d82fa9ddca6580e3255b1
【讨论】:
这行得通,谢谢!但是使用 min,当您实际上不是在寻找最小值时会有点混乱。MIN
只是将其作为聚合列,因此您可以按app_id
分组。我假设app_id
和service_name
的每个组合只会返回一个不同的result
值。如果不是这样,您将需要在您的要求中指定一些不同的规则。【参考方案2】:
您可以使用以下查询。产生所需的结果。
select t2.app_id,
max(case when service_name = 'service_1' then result end) as service_1_res,
max(case when service_name = 'service_2' then result end) as service_2_res
from
(select app_id
from tb1
where tb1.service_name in ('service_1', 'service_2')
group by app_id
having count(app_id) > 1) t1
join
tb1 t2 on t1.app_id = t2.app_id
where t2.service_name not in ('service_3')
group by t2.app_id
【讨论】:
【参考方案3】:这可以通过 Pivot 来实现。该解决方案可通过此链接访问-http://sqlfiddle.com/#!18/df2d1/4
select * from
(
select app_id, service_name, result
from myTable
) as mt
pivot
(
max(result)
for [service_name] in (service_1, service_2)
) as pt
【讨论】:
非常感谢 san_raj。我喜欢你的回答。但实际上我的任务中有另一个“约束”,我在问题中没有提到(因为当时它似乎并不重要)。对于每项服务,我需要从 json (结果)中获取一个值,并且 json 中的“路由”对于每个服务都是不同的。但我相信现在我可以自己解决了。以上是关于如何从一列的不同行中获取值以分隔列的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Access 2016 中的另一列上选择具有最大值的不同行