Sql 按查询自定义分组

Sql 按查询自定义分组,sql,ansi-sql,Sql,Ansi Sql,我有一个包含三列的表格:EmployeeID,部门,位置 每个员工可能有多个部门,并且可以位于多个地点 通过对任何RDBMS的SQL查询, 我需要针对每个EmployeeID返回不同的部门集(用连字符分隔)、不同的位置集(用连字符分隔) 对于以下以DB表示的记录 环境管理计划1,人力资源部,加尔各答 EMP1,人力资源部,德里 EMP1,设施,孟买 环境管理计划1,设施,加尔各答 我需要得到以下结果:EMP1,人力资源设施,加尔各答-德里-孟买 欢迎提供任何帮助。在ANSI SQL中,我能想到的

我有一个包含三列的表格:EmployeeID部门位置

每个员工可能有多个部门,并且可以位于多个地点

通过对任何RDBMS的SQL查询, 我需要针对每个EmployeeID返回不同的部门集(用连字符分隔)、不同的位置集(用连字符分隔)

对于以下以DB表示的记录

  • 环境管理计划1,人力资源部,加尔各答

  • EMP1,人力资源部,德里

  • EMP1,设施,孟买

  • 环境管理计划1,设施,加尔各答

  • 我需要得到以下结果:EMP1,人力资源设施,加尔各答-德里-孟买


    欢迎提供任何帮助。

    在ANSI SQL中,我能想到的唯一方法是使用
    densite\u rank()
    和条件聚合。假设每组的值不超过三个:

    select empid,
           trim(trailing '-' from
                concat( max(case when l_seqnum = 1 then concat(location, '-') else '' end),
                        max(case when l_seqnum = 2 then concat(location, '-') else '' end),
                        max(case when l_seqnum = 3 then concat(location, '-') else '' end)
               ) as locations,
           trim(trailing '-' from
                concat( max(case when d_seqnum = 1 then concat(department, '-') else '' end),
                        max(case when d_seqnum = 2 then concat(department, '-') else '' end),
                        max(case when d_seqnum = 3 then concat(department, '-') else '' end)
               ) as departments
    from (select t.*,
                 dense_rank() over (partition by empid order by department) as d_seqnum,
                 dense_rank() over (partition by empid order by location) as l_seqnum
          from table t
         ) t
    group by empid;
    

    但是,大多数数据库都有更合理的方式来表达这一点。

    您使用的是什么数据库?请适当标记您的问题。@GordonLinoff,查询必须是ANSI-SQL才能在任何RDBMSI中运行。我不认为这是可能的,因为ANSI SQL标准中没有定义行内聚合函数。通常,您可以使用SQL server的东西或Oracle的Listag来实现这一点。如果它必须保持通用性,您最好编写代码(C#,java等)来进行聚合。@booyaa好的,您可以使用子查询来完成它。。。如果varchars上有
    sum
    ,而实际上没有。羞耻:)也许您可以创建一个用户定义的函数,该函数对于不同的数据库引擎会有所不同?在任何情况下,针对ANSI-SQL编码并期望它在任何RDBMS上运行(并且运行良好!)都是幼稚的。这种方式仍然不能很好地工作。我认为使用ANSI_SQL也不可能。您需要一个数据库sepcific方法来解决这个问题,或者需要一个PL/SQL块来很好地完成,尽管我必须在oracle中成对地包装位置和部门concat调用[
    concat(concat(a,B),C)
    ],才能使其工作。我认为TRIM是一个oracle调用,只有SQL 2008才可以使用,所以可能是在更高版本中引入的。@booyaa。没有人,尤其是Oracle,会建议他们支持ANSI SQL。在Oracle中,您只需使用连接运算符(
    | |
    ),ANSI也支持该运算符。但是有更好的方法在Oracle中编写查询。正如我在回答中所说,这是ANSI SQL,但它可能不是在任何实际数据库中表达查询的最佳方式。