【问题标题】:SQL Server String Concat with StuffSQL Server 字符串与东西连接
【发布时间】:2016-06-22 12:13:44
【问题描述】:

几天前我在网上查看了如何在 sql server 上使用 STUFF,我看到的大多数示例只涉及两个表,而我的查询正在通过 3 个表,但我无法让它工作这是没有 STUFF 函数的查询,它可以获取我想要的所有数据:

select c.category_name,r.role_name
from categories as c 
join role_categ as rc on c.category_id=rc.category_id 
join roles as r on r.role_id=rc.role_id
where rc.c_read='1';

我想要的是你有一个 Category_name 然后 Id 想要所有 role_names 在第一行的一个单元格中:

BCM-Télécopieur-影印机 Admin,Administation

这里有什么东西功能但不工作jsut给了我与其他查询相同的表

select c.category_name,STUFF((
    select ','+r.role_name
    from roles as r
    where rc.role_id=r.role_id
    for xml path('')),1,1,'')
from role_categ as rc
join categories as c on c.category_id=rc.category_id

任何帮助将不胜感激。

【问题讨论】:

  • 尝试将SELECT DISTINCT添加到主查询并将,更改为-
  • STUFF 不进行任何字符串连接。 FOR XML 在这里做繁重的工作,并产生了一个类似,abc,def,ghi 的字符串。 STUFF 所做的只是删除前导逗号。

标签: sql sql-server string tsql concat


【解决方案1】:

这是我想出的一个版本。 @GiorgosBetsos 是正确的,JOIN 需要移动到内部查询。我不确定他为什么仍然看到重复,但以下查询按预期返回数据:

-- Set up the data
DECLARE @roles TABLE (role_id INT, role_name VARCHAR(20))
DECLARE @role_categories TABLE (category_id INT, role_id INT)
DECLARE @categories TABLE (category_id INT, category_name VARCHAR(20))

INSERT INTO @roles (role_id, role_name) VALUES (1, 'Admin'), (2, 'Administration'), (3, 'Tech')
INSERT INTO @categories (category_id, category_name) VALUES (1, 'Consultant'), (2, 'FTP'), (3, 'Logicals')
INSERT INTO @role_categories (category_id, role_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1)

-- The query
SELECT
    C.category_name,
    STUFF((
        SELECT ',' + R.role_name
        FROM
            @role_categories RC
        INNER JOIN @roles R ON R.role_id = RC.role_id
        WHERE
            RC.category_id = C.category_id AND
            RC.c_read = 1
        FOR XML PATH('')), 1, 1, '')
FROM
    @categories C

【讨论】:

  • 主查询不执行JOINrole_categ,所以你不会得到重复。不过,在 OP 中提到的查询中还有一个额外的谓词 c_read = '1',所以我猜你还必须加入 role_categ
  • 我已将c_read 添加到内部查询中。我正在离开问题中的最后一个陈述,所以我错过了那部分。它仍然可以正常工作,没有重复。您仍然只需要在查询中使用一次role_categ
【解决方案2】:

试试这个:

SELECT DISTINCT c_out.category_name,
       STUFF((SELECT ',' + r.role_name
              FROM roles as r
              INNER JOIN role_categ as rc ON rc.role_id=r.role_id
              WHERE rc_out.category_id=rc.category_id
              FOR XML PATH('')),1,1,'')
FROM role_categ AS rc_out
JOIN categories AS c_out ON c_out.category_id = rc_out.category_id
WHERE rc_out.c_read = '1'

您需要在子查询中将JOINrole_categ 表关联起来,以便与category_id 相关联。此外,您必须在外部查询中使用DISTINCT 以过滤掉重复记录。

【讨论】:

  • 如果内部查询中只有 JOIN,我认为可以取消 DISTINCT
  • @TomH 我已经用我自己的样本数据测试了查询,它返回没有DISTINCT 的重复项。
  • 不知道那是什么交易,因为我已经运行了我自己的版本和您的查询的修改版本,没有DISTINCT,没有任何问题。我会把它贴在下面作为答案,也许你会发现我错过的东西。
  • 完善了这项工作,解释也很棒我实际上理解了我哪里出错了谢谢,但是有些结果有技术,他们不应该有他们都有管理员,技术,管理,其中只有三个他们应该有技术
  • @therrienri 你能提供一些示例数据吗?
猜你喜欢
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 2017-05-11
  • 1970-01-01
  • 2013-01-11
相关资源
最近更新 更多