打破我的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礼仪,请尽量不要让我太生气。请指出它,下次我会尽力做得更好。)
答案 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可能更适合直接从应用程序调用。