【问题标题】:Custom group by query按查询自定义分组
【发布时间】:2015-04-07 12:18:12
【问题描述】:

我有一个包含三列的表:EmployeeID、Department、Location

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

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

对于DB中的以下记录,

  1. EMP1,人力资源部,加尔各答

  2. EMP1,人力资源部,德里

  3. EMP1,设施,孟买

  4. EMP1,设施,加尔各答

我需要得到以下结果:EMP1, HR-Facility, Kolkata-Delhi-Mumbai

欢迎任何帮助。

【问题讨论】:

  • 您使用的是什么数据库?请适当标记您的问题。
  • @GordonLinoff,查询必须是 ANSI-SQL 才能在任何 RDBMS 中运行
  • 我认为这是不可能的,因为 ANSI SQL 标准中没有定义行内聚合函数。通常,您可以使用 SQL Server 的 STUFF 或 Oracle 的 LISTAGG 来实现此目的。如果它必须保持通用,您最好编写代码(C#、java 等)来进行聚合。
  • @booyaa 好吧,你可以用子查询来做到这一点......如果有sum over varchars,但没有。耻辱 :) 也许您可以创建一个用户定义的函数,该函数对于不同的数据库引擎会有所不同?在任何情况下,针对 ANSI-SQL 进行编码并期望它在任何 RDBMS 上运行(并且运行良好!)都是幼稚的。它仍然不能那样工作。
  • 我认为 ANSI_SQL 也不可能。你需要一个数据库特定的方法来解决这个问题,或者一个 PL/SQL 块

标签: sql ansi-sql


【解决方案1】:

我能想到在 ANSI SQL 中执行此操作的唯一方法是使用 dense_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;

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

【讨论】:

  • 做得很好,尽管我必须在 oracle 中将位置和部门 concat 调用配对 [CONCAT(CONCAT(A,B),C)] 才能使其正常工作。而且我认为 TRIM 是一个 oracle 调用,只有 SQL 2008 方便,所以它可能是在以后的版本中引入的。
  • @booyaa 。 . .没有人,尤其是 Oracle,会建议他们支持 ANSI SQL。在 Oracle 中,您只需使用连接运算符 (||),ANSI 也支持该运算符。但是有更好的方法可以在 Oracle 中编写查询。正如我在回答中所说,这是 ANSI SQL,但它可能不是在任何真实数据库中表达查询的最佳方式。
猜你喜欢
  • 2010-12-23
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
  • 2015-08-17
  • 1970-01-01
  • 2010-12-23
  • 2017-04-18
  • 1970-01-01
相关资源
最近更新 更多