SQL Server条件组

时间:2011-08-04 23:24:18

标签: sql-server sql-server-2008

打破我的stackoverflow.com樱桃!

我有一个SQL Server 2008表,其中包含10个nchar(1)列。我试图编写一个存储过程来查询表,以获得按十列任意组合分组的计数。例如,假设我在表格中有这些行:

| COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL7 | COL8 | COL9 | COL10
+======+======+======+======+======+======+======+======+======+======
|  T   |  P   |  9   |  C   |  )   |  N   |  N   |  S   |  X   |  X   
|  T   |  P   |  9   |  7   |  0   |  *   |  N   |  Q   |  X   |  X   
|  T   |  P   |  I   |  B   |  (   |  H   |  N   |  S   |  X   |  X   
|  T   |  P   |  A   |  A   |  G   |  S   |  N   |  6   |  X   |  X   

我希望能够对第1列和第3列进行分组并获得:

COUNT | COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL7 | COL8 | COL9 | COL10
+=====+======+======+======+======+======+======+======+======+=============
|   2 |  T   |  -   |  9   |  -   |  -   |  -   |  -   |  -   |  -   |  -   
|   1 |  T   |  -   |  A   |  -   |  -   |  -   |  -   |  -   |  -   |  -   
|   1 |  T   |  -   |  I   |  -   |  -   |  -   |  -   |  -   |  -   |  -   

或者我希望能够对第1,2和8列进行分组并获得:

COUNT | COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL7 | COL8 | COL9 | COL10
+=====+======+======+======+======+======+======+======+======+=============
|   2 |  T   |  P   |  -   |  -   |  -   |  -   |  -   |  S   |  -   |  -   
|   1 |  T   |  P   |  -   |  -   |  -   |  -   |  -   |  6   |  -   |  -   
|   1 |  T   |  P   |  -   |  -   |  -   |  -   |  -   |  Q   |  -   |  -   

我想我可以在客户端动态创建查询并完成它。我认为这是目前最简单的解决方案。但是为了将来参考,有一种简单的方法可以在服务器端上执行此操作而不使用动态SQL ?好吧,我一直认为动态SQL 通常是一个坏主意。在这种情况下它会是首选方法吗?

(如果我没有遵循stackoverflow.com礼仪,请尽量不要让我太生气。请指出它,下次我会尽力做得更好。)

1 个答案:

答案 0 :(得分:5)

CREATE PROCEDURE GetGroups (
  @Col1 bit,
  @Col2 bit,
  @Col3 bit,
  @Col4 bit,
  @Col5 bit,
  @Col6 bit,
  @Col7 bit,
  @Col8 bit,
  @Col9 bit,
  @Col10 bit
)
AS
SELECT
  COUNT = COUNT(*),
  CASE @col1  WHEN 1 THEN COL1  END COL1,
  CASE @col2  WHEN 1 THEN COL2  END COL2,
  CASE @col3  WHEN 1 THEN COL3  END COL3,
  CASE @col4  WHEN 1 THEN COL4  END COL4,
  CASE @col5  WHEN 1 THEN COL5  END COL5,
  CASE @col6  WHEN 1 THEN COL6  END COL6,
  CASE @col7  WHEN 1 THEN COL7  END COL7,
  CASE @col8  WHEN 1 THEN COL8  END COL8,
  CASE @col9  WHEN 1 THEN COL9  END COL9,
  CASE @col10 WHEN 1 THEN COL10 END COL10
FROM YourTable
GROUP BY
  CASE @col1  WHEN 1 THEN COL1  END,
  CASE @col2  WHEN 1 THEN COL2  END,
  CASE @col3  WHEN 1 THEN COL3  END,
  CASE @col4  WHEN 1 THEN COL4  END,
  CASE @col5  WHEN 1 THEN COL5  END,
  CASE @col6  WHEN 1 THEN COL6  END,
  CASE @col7  WHEN 1 THEN COL7  END,
  CASE @col8  WHEN 1 THEN COL8  END,
  CASE @col9  WHEN 1 THEN COL9  END,
  CASE @col10 WHEN 1 THEN COL10 END

<强>更新

顺便说一句,由于生成的查询不是动态构造的,因此可以将其实现为表值函数:

CREATE FUNCTION fnGetGroups (
  @Col1 bit,
  @Col2 bit,
  @Col3 bit,
  @Col4 bit,
  @Col5 bit,
  @Col6 bit,
  @Col7 bit,
  @Col8 bit,
  @Col9 bit,
  @Col10 bit
)
RETURNS TABLE
AS
RETURN (
  SELECT
  …
)

并从SP中调用它:

CREATE PROCEDURE GetGroups (
  @Col1 bit,
  @Col2 bit,
  @Col3 bit,
  @Col4 bit,
  @Col5 bit,
  @Col6 bit,
  @Col7 bit,
  @Col8 bit,
  @Col9 bit,
  @Col10 bit
)
AS
SELECT *
FROM fnGetGroups(@Col1, @Col2, @Col3, @Col4, @Col5,
                 @Col6, @Col7, @Col8, @Col9, @Col10)

问题是,TVF可以在各种SQL脚本中使用,而SP可能更适合直接从应用程序调用。