如何通过主键将元数据附加到分组选择
How to append metadata to a grouped selection by primary key
我有一个收藏夹列表,例如:
示例数据
| key | item_id | list_name | customer_id |meta |
|-----|---------|-----------|--------------|---------------|
| 1 | A-11 | aa11 | 001 | unique-data-1 |
| 2 | A-11 | bb22 | 001 | unique-data-2 |
| 3 | A-26 | cc33 | 001 | unique-data-3 |
| 4 | A-28 | aa11 | 002 | unique-data-4 |
| 5 | J-52 | aa11 | 001 | unique-data-5 |
| 6 | X-53 | aa11 | 001 | unique-data-6 |
期望输出
对于@item_id nvarchar(20) = 'A-11'
| key | isFavorited | list_name | meta |
|-----|-------------|-----------|---------------|
| 1 | Y | aa11 | unique-data-1 |
| 2 | Y | bb22 | unique-data-2 |
| 3 | N | cc33 | unique-data-3 |
并且想return select所有可用列表的离子,以及特定项目是否是该列表的一部分,及其元数据。
declare @item_id nvarchar(20) = 'A-11'
declare @customer_id nvarchar(20) = 001
select
[key],
[isFavorited] = max(case when [item_id] = @item_id then 'Y' else 'N' end)
[list_name]
[meta]
from favorites
where customer_id = @customer_id
group by [list_name], [key], [meta]
尝试各种方法时出现的问题:
我遇到的问题是,由于 meta
是唯一的,分组依据破坏了 select
的唯一性
像下面这样的交叉应用不会根据匹配的 key
.
应用正确的 meta
cross apply (
select top 1
[meta]
from favorites
where customer_id = @customer_id
)
当按行号 select 时,要加入的实际 key
丢失了,所以我无法加入 meta
。
"noRow" = row_number() over(order by h_po_no asc)
我愿意
- 传入一个
item_id
和customer_id
- Return 该客户的所有列表
- 获取传入的每个列表的收藏状态
item_id
- 如果某项与给定的
customer_id
customer_id
匹配 list_name
和 item_id
,则该项目被标记为收藏
- 获取主要行
key
和 meta
数据
我怎样才能 return select 一个 list_name
、isFavorite
状态、key
的独特 select 离子,并且它是 meta
?
要return 所需的输出,您根本不需要任何聚合。一个简单的 case 表达式和一个 where 子句就可以做到这一点。
declare @Favorites table
(
MyKey int
, item_id varchar(10)
, list_name varchar(10)
, customer_id varchar(10)
, meta varchar(20)
)
insert @Favorites values
(1, 'A-1', 'list-1', '001', 'unique-data-1')
, (2, 'A-1', 'list-2', '001', 'unique-data-2')
, (3, 'A-2', 'list-3', '001', 'unique-data-3')
, (4, 'A-2', 'list-1', '002', 'unique-data-1')
select *
from @Favorites
declare @item_id nvarchar(20) = 'A-1'
, @customer_id nvarchar(20) = '001'
select f.MyKey
, isFavorited = case when f.item_id = @item_id then 'Y' else 'N' end
, listName = f.list_name
, f.meta
from favorites f
where f.customer_id = @customer_id
order by f.MyKey
测试参数
declare @item_id nvarchar(20) = 'A-11'
declare @customer_id nvarchar(20) = 001
解决方案
drop table if exists #tmp
;with cte as (
select
[key],
[list_name],
[rn] = row_number() over (partition by list_name order by list_name desc)
from favorites
where customer_id = @customer_id
group by [list_name], [key], [meta]
)
select *
into #tmp
from cte
where [rn] = 1
select
[i],
[json],
#t.[tmp]
from #tmp #t
inner join (
select
[isFavorited] = max(case when [item_id] = @item_id then 'Y' else 'N' end)
[list_name]
from favorites
where customer_id = @customer_id
group by [list_name]
) j
on j.list_name = #t.list_name
我有一个收藏夹列表,例如:
示例数据
| key | item_id | list_name | customer_id |meta |
|-----|---------|-----------|--------------|---------------|
| 1 | A-11 | aa11 | 001 | unique-data-1 |
| 2 | A-11 | bb22 | 001 | unique-data-2 |
| 3 | A-26 | cc33 | 001 | unique-data-3 |
| 4 | A-28 | aa11 | 002 | unique-data-4 |
| 5 | J-52 | aa11 | 001 | unique-data-5 |
| 6 | X-53 | aa11 | 001 | unique-data-6 |
期望输出
对于@item_id nvarchar(20) = 'A-11'
| key | isFavorited | list_name | meta |
|-----|-------------|-----------|---------------|
| 1 | Y | aa11 | unique-data-1 |
| 2 | Y | bb22 | unique-data-2 |
| 3 | N | cc33 | unique-data-3 |
并且想return select所有可用列表的离子,以及特定项目是否是该列表的一部分,及其元数据。
declare @item_id nvarchar(20) = 'A-11'
declare @customer_id nvarchar(20) = 001
select
[key],
[isFavorited] = max(case when [item_id] = @item_id then 'Y' else 'N' end)
[list_name]
[meta]
from favorites
where customer_id = @customer_id
group by [list_name], [key], [meta]
尝试各种方法时出现的问题:
我遇到的问题是,由于
meta
是唯一的,分组依据破坏了 select 的唯一性
像下面这样的交叉应用不会根据匹配的
应用正确的key
.meta
cross apply ( select top 1 [meta] from favorites where customer_id = @customer_id )
当按行号 select 时,要加入的实际
key
丢失了,所以我无法加入meta
。"noRow" = row_number() over(order by h_po_no asc)
我愿意
- 传入一个
item_id
和customer_id
- Return 该客户的所有列表
- 获取传入的每个列表的收藏状态
item_id
- 如果某项与给定的
customer_id
customer_id
匹配
list_name
和item_id
,则该项目被标记为收藏 - 如果某项与给定的
- 获取主要行
key
和meta
数据
我怎样才能 return select 一个 list_name
、isFavorite
状态、key
的独特 select 离子,并且它是 meta
?
要return 所需的输出,您根本不需要任何聚合。一个简单的 case 表达式和一个 where 子句就可以做到这一点。
declare @Favorites table
(
MyKey int
, item_id varchar(10)
, list_name varchar(10)
, customer_id varchar(10)
, meta varchar(20)
)
insert @Favorites values
(1, 'A-1', 'list-1', '001', 'unique-data-1')
, (2, 'A-1', 'list-2', '001', 'unique-data-2')
, (3, 'A-2', 'list-3', '001', 'unique-data-3')
, (4, 'A-2', 'list-1', '002', 'unique-data-1')
select *
from @Favorites
declare @item_id nvarchar(20) = 'A-1'
, @customer_id nvarchar(20) = '001'
select f.MyKey
, isFavorited = case when f.item_id = @item_id then 'Y' else 'N' end
, listName = f.list_name
, f.meta
from favorites f
where f.customer_id = @customer_id
order by f.MyKey
测试参数
declare @item_id nvarchar(20) = 'A-11'
declare @customer_id nvarchar(20) = 001
解决方案
drop table if exists #tmp
;with cte as (
select
[key],
[list_name],
[rn] = row_number() over (partition by list_name order by list_name desc)
from favorites
where customer_id = @customer_id
group by [list_name], [key], [meta]
)
select *
into #tmp
from cte
where [rn] = 1
select
[i],
[json],
#t.[tmp]
from #tmp #t
inner join (
select
[isFavorited] = max(case when [item_id] = @item_id then 'Y' else 'N' end)
[list_name]
from favorites
where customer_id = @customer_id
group by [list_name]
) j
on j.list_name = #t.list_name