2011-08-04 4 views
4

Busting my stackoverflow.com cherry!Groupe conditionnel SQL Server Par

J'ai une table SQL Server 2008 qui contient dix colonnes nchar (1). J'essayais d'écrire un proc stocké pour interroger la table pour obtenir les comptes groupés par n'importe quelle combinaison des dix colonnes. Par exemple, disons que j'ai ces lignes dans la table:

| 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 

Je veux être en mesure de groupe sur les colonnes 1 et 3 et obtenez:

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

Ou je veux être en mesure de regrouper sur colonnes 1, 2 et 8 et obtenez:

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

Je pense que je peux créer dynamiquement la requête sur le côté client et être fait avec elle. Je pense que ce serait la solution la plus simple en ce moment. Mais pour référence future est-il un moyen simple de le faire sur le côté serveur sans utiliser SQL dynamique? Eh bien, j'ai toujours lu que SQL dynamique est habituellement une mauvaise idée. Serait-ce la méthode préférée dans ce cas?

(Essayez de ne pas me flamme trop mal si je ne l'ai pas suivi stackoverflow.com étiquette. S'il vous plaît indiquer simplement dehors et je vais essayer de faire mieux la prochaine fois.)

Répondre

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 

MISE à JOUR

Par ailleurs, étant donné que la requête résultante n'est pas construit dynamiquement, vous pouvez le mettre en œuvre en fonction de la table-valeur:

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 
    … 
) 

et appeler au lieu de la 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) 

La chose est, un TVF peut être plus pratique à utiliser dans différents scripts SQL, alors qu'un SP pourrait être préférable d'appeler directement depuis l'application.

+0

Wow. Impressionnant. Je vous remercie. – Frank