SQL Server条件组

Fra*_*ank 4 sql-server sql-server-2008

打破我的stackoverflow.com樱桃!

我有一个SQL Server 2008表,其中包含十个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   
Run Code Online (Sandbox Code Playgroud)

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

COUNT | COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL7 | COL8 | COL9 | COL10
+=====+======+======+======+======+======+======+======+======+=============
|   2 |  T   |  -   |  9   |  -   |  -   |  -   |  -   |  -   |  -   |  -   
|   1 |  T   |  -   |  A   |  -   |  -   |  -   |  -   |  -   |  -   |  -   
|   1 |  T   |  -   |  I   |  -   |  -   |  -   |  -   |  -   |  -   |  -   
Run Code Online (Sandbox Code Playgroud)

或者我希望能够对第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   |  -   |  -   
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*y M 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
Run Code Online (Sandbox Code Playgroud)

UPDATE

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

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
  …
)
Run Code Online (Sandbox Code Playgroud)

而是从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)
Run Code Online (Sandbox Code Playgroud)

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