SQL Server:limit string_agg结果

发布于 2025-01-25 23:34:37 字数 269 浏览 3 评论 0原文

我有以下查询(为每个客户显示用户列表):

select cu.customer_id , STRING_AGG(u.first_name + ' ' + u.last_name , ',') as users   
from customer_user cu join user u on cu.user_id = u.id   
where ... 
group by cu.customer_id

如何限制string_agg函数以汇总每个组的10个元素?

I have the following query (showing for each customer the list of users):

select cu.customer_id , STRING_AGG(u.first_name + ' ' + u.last_name , ',') as users   
from customer_user cu join user u on cu.user_id = u.id   
where ... 
group by cu.customer_id

How can I limit the string_agg function to aggregate only 10 elements for each group?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花桑 2025-02-01 23:34:37

您可以尝试编号行:

SELECT customer_id , STRING_AGG(first_name + ' ' + last_name , ',') AS users   
FROM (
   SELECT 
      cu.customer_id, u.first_name, u.last_name,
      ROW_NUMBER() OVER (PARTITION BY cu.customer_id ORDER BY (SELECT NULL)) AS rn
   FROM customer_user cu 
   JOIN user u ON cu.user_id = u.id
   -- WHERE ...
) t
WHERE rn <= 10
GROUP BY customer_id

You may try to number the rows:

SELECT customer_id , STRING_AGG(first_name + ' ' + last_name , ',') AS users   
FROM (
   SELECT 
      cu.customer_id, u.first_name, u.last_name,
      ROW_NUMBER() OVER (PARTITION BY cu.customer_id ORDER BY (SELECT NULL)) AS rn
   FROM customer_user cu 
   JOIN user u ON cu.user_id = u.id
   -- WHERE ...
) t
WHERE rn <= 10
GROUP BY customer_id
岁月苍老的讽刺 2025-02-01 23:34:37

同样,这是我发现逻辑的“丑陋”部分(串联和确定“第一个”或“任何“ 10”)的另一种情况,然后直到以后直到以后才聚集:

; -- see sqlblog.org/cte
WITH src AS
(
  SELECT cu.customer_id, n = CONCAT(u.first_name, ' ', u.last_name),
      rn = ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY @@SPID)
    FROM dbo.customer_user AS cu
    INNER JOIN dbo.[user] AS u -- bad table name
    ON cu.user_id = u.id
    /* WHERE ... */
)
SELECT customer_id, users = STRING_AGG(n, N',')
  FROM src
  WHERE rn <= 10
  GROUP BY customer_id;

Again this is another case where I find separating the "ugly" part of the logic (concatenation and determining "first" or "any" 10) in a CTE, then not aggregating until after:

; -- see sqlblog.org/cte
WITH src AS
(
  SELECT cu.customer_id, n = CONCAT(u.first_name, ' ', u.last_name),
      rn = ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY @@SPID)
    FROM dbo.customer_user AS cu
    INNER JOIN dbo.[user] AS u -- bad table name
    ON cu.user_id = u.id
    /* WHERE ... */
)
SELECT customer_id, users = STRING_AGG(n, N',')
  FROM src
  WHERE rn <= 10
  GROUP BY customer_id;
如果没有 2025-02-01 23:34:37

我们可以在子问题中使用row_number。在此示例中,我限制为2,您可以将RN的限制更改为10或其他数字。
我显示第一个查询没有限制,第二个查询以显示差异。

 创建表用户(
  id int, 
  first_name varchar(25),
  last_name varchar(25)
  );
插入用户值
(1,'andrew','a'),
(2,'bill','b'),
(3,'charlie','c');
创建表Customer_user(
  customer_id int,
  user_id int);
插入customer_user值
(1,1),(1,2),(1,3);
去
 
 

6行影响

 选择 
  cu.customer_id, 
  用户   
来自customer_user cu在cu.user_id = u.id上加入用户u  
组由Cu.customer_id
 
  GO
 
 customer_id |用户                    
-----------:| :----------------------------------
          1 | Andrew A,Bill B,Charlie C
 选择
  u.customer_id, 
  用户   
从 (
  选择
    row_number()over(customer_id订单分区u.id)rn,
    cu.customer_id,
    u.first_name,
    u.last_name
  来自Customer_user Cu 
  加入用户u上的cu.user_id = u.id  
  )u
rn&lt; 3
u.customer_id的组
去
 
 customer_id |用户          
-----------:| :-------------------
          1 | Andrew A,Bill b

db&lt;&gt;&gt;

We can use row_number in a sub-query. I have limited to 2 in this example and you can change the limit for rn as to 10, or other number.
I show the first query without a limit and the second with a limit to show the difference.

create table users(
  id int, 
  first_name varchar(25),
  last_name varchar(25)
  );
insert into users values
(1,'Andrew','A'),
(2,'Bill','B'),
(3,'Charlie','C');
create table customer_user(
  customer_id int,
  user_id int);
insert into customer_user values
(1,1),(1,2),(1,3);
GO

6 rows affected

select 
  cu.customer_id , 
  STRING_AGG(u.first_name + ' ' + u.last_name , ',') as users   
from customer_user cu join users u on cu.user_id = u.id  
group by cu.customer_id
GO
customer_id | users                    
----------: | :------------------------
          1 | Andrew A,Bill B,Charlie C
select
  u.customer_id , 
  STRING_AGG(u.first_name + ' ' + u.last_name , ',') as users   
from (
  select
    row_number() over(partition by customer_id order by u.id) rn,
    cu.customer_id,
    u.first_name,
    u.last_name
  from customer_user cu 
  join users u on cu.user_id = u.id  
  ) u
where rn < 3
group by u.customer_id
GO
customer_id | users          
----------: | :--------------
          1 | Andrew A,Bill B

db<>fiddle here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文