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