2009-01-31 7 views
0

J'apprécierais vraiment l'aide avec ceci, je suis sérieusement bloqué. Fondamentalement, j'ai une table quiSQL 2005 SELECT CASE <column> déclaration

ressemble à ceci:

SSS_DOWID Name Mon Tue Wed Thu Fri Sat Sun Description 
2   M Y N N N  N  N  N  Monday 
3   MF Y N N N  Y  N  N  Monday, Friday 
....... 
18  T N Y N N  N  N  N  Tuesday 
........ 
etc. 

Ce que je dois faire est de convertir les valeurs dans ce tableau à une table qui ne contient que les

chiffres correspondants pour les jours la semaine, par exemple, 1 pour dimanche, 2 pour lundi, 3 pour mardi, etc., tout le chemin jusqu'à 8 pour dimanche.

SO Je possède ce peu de SQL:

DECLARE @strDays table 
(SSS_DOWID int) 

INSERT INTO @strDays 
SELECT 
    case (sun) when 'Y' then '1' else '' end + 
    case (mon) when 'Y' then '2' else '' end + 
    case (tue) when 'Y' then '3' else '' end + 
    case (wed) when 'Y' then '4' else '' end + 
    case (thu) when 'Y' then '5' else '' end + 
    case (fri) when 'Y' then '6' else '' end + 
    case (sat) when 'Y' then '7' else '' end 
FROM 
    [dbo].SSS_DOW WITH (NOLOCK) 
WHERE 
    SSS_DOWID IN (28,41,44) 

SELECT * FROM @strDays 

Ce qui fonctionne bien pour certains jours, SAUF combinaisons de jour. Donc, dans ce cas, quand je passe en

28 (mer), 41 (ven), et 44 (SaSun), je reçois 4 (parfait), 6 (parfait), et 17 (oh merde - devrait être

1 et 7, séparément).

Quelqu'un peut-il me aider s'il vous plaît restructure mon SQL si je reçois une table contenant 1, 4, 6 et 7 au lieu

de 4, 6, 17?

Répondre

2

Il semble que vous ayez besoin d'un pivot.

DECLARE @Days TABLE 
(
    DayId int PRIMARY KEY, 
    found int 
) 

INSERT INTO @Days(DayId, found) SELECT 1, 0 
INSERT INTO @Days(DayId, found) SELECT 2, 0 
INSERT INTO @Days(DayId, found) SELECT 3, 0 
INSERT INTO @Days(DayId, found) SELECT 4, 0 
INSERT INTO @Days(DayId, found) SELECT 5, 0 
INSERT INTO @Days(DayId, found) SELECT 6, 0 
INSERT INTO @Days(DayId, found) SELECT 7, 0 
-- 
UPDATE d 
SET d.found = 1 
FROM @Days d JOIN SSS_DOW s 
    ON 
CASE 
    WHEN d.DayId = 1 and s.Mon == 'Y' THEN 1 
    WHEN d.DayId = 2 and s.Tue == 'Y' THEN 1 
    WHEN d.DayId = 3 and s.Wed == 'Y' THEN 1 
    WHEN d.DayId = 4 and s.Thu == 'Y' THEN 1 
    WHEN d.DayId = 5 and s.Fri == 'Y' THEN 1 
    WHEN d.DayId = 6 and s.Sat == 'Y' THEN 1 
    WHEN d.DayId = 7 and s.Sun == 'Y' THEN 1 
    ELSE 0 
    END = 1 
WHERE SSS_DowID in (28, 41, 44) 
-- 
SELECT * 
FROM @Days 
WHERE found = 1 
0

Essayez de faire sept déclarations d'insertion:

INSERT INTO @strDays 
    SELECT SSS_DOWID, 1 FROM SSS_DOW WHERE SSS_DOWID IN (28,41,44) AND Sun = 'Y'; 


INSERT INTO @strDays 
    SELECT SSS_DOWID, 2 FROM SSS_DOW WHERE SSS_DOWID IN (28,41,44) AND Mon = 'Y'; 

etc. 
1
WITH days AS (
    SELECT SSS_DOWID, 1 AS DayOfWeek FROM dbo.SSS_DOW WHERE sun = 'Y' 
    UNION ALL 
    SELECT SSS_DOWID, 2 AS DayOfWeek FROM dbo.SSS_DOW WHERE mon = 'Y' 
    UNION ALL 
    SELECT SSS_DOWID, 3 AS DayOfWeek FROM dbo.SSS_DOW WHERE tue = 'Y' 
    UNION ALL 
    SELECT SSS_DOWID, 4 AS DayOfWeek FROM dbo.SSS_DOW WHERE wed = 'Y' 
    UNION ALL 
    SELECT SSS_DOWID, 5 AS DayOfWeek FROM dbo.SSS_DOW WHERE thu = 'Y' 
    UNION ALL 
    SELECT SSS_DOWID, 6 AS DayOfWeek FROM dbo.SSS_DOW WHERE fri = 'Y' 
    UNION ALL 
    SELECT SSS_DOWID, 7 AS DayOfWeek FROM dbo.SSS_DOW WHERE sat = 'Y') 
SELECT DayOfWeek 
FROM days 
WHERE SSS_DOWID IN (28,41,44); 
1

Il me semble que vous citez vos numéros:

case (sun) when 'Y' then '1' else '' end + 
case (mon) when 'Y' then '2' else '' end + 

Alors ce que vous obtenez lorsque vous utilisez « + C'est la concaténation au lieu de l'addition. C'est pourquoi vous obtenez 17 votre réponse. Pour la décomposer en deux réponses séparées dans une colonne, vous devrez peut-être essayer l'une des réponses énumérées ici.

1

Dans SQL Server 2005, vous pouvez utiliser le UNPIVOT explicite:

/* 
CREATE TABLE SSS_DOW (
    SSS_DOWID int NOT NULL 
    ,[Name] varchar(50) NOT NULL 
    ,Mon char(1) NOT NULL 
    ,Tue char(1) NOT NULL 
    ,Wed char(1) NOT NULL 
    ,Thu char(1) NOT NULL 
    ,Fri char(1) NOT NULL 
    ,Sat char(1) NOT NULL 
    ,Sun Char(1) NOT NULL 
    ,[Description] varchar(50) NOT NULL 
) 

INSERT INTO SSS_DOW VALUES (2, 'M', 'Y', 'N', 'N', 'N', 'N', 'N', 'N', 'Monday') 
INSERT INTO SSS_DOW VALUES (3, 'MF', 'Y', 'N', 'N', 'N', 'Y', 'N', 'N', 'Monday, Friday') 
INSERT INTO SSS_DOW VALUES (28, 'W', 'N', 'N', 'Y', 'N', 'N', 'N', 'N', 'Wednesday') 
INSERT INTO SSS_DOW VALUES (41, 'F', 'N', 'N', 'N', 'N', 'Y', 'N', 'N', 'Friday') 
INSERT INTO SSS_DOW VALUES (44, 'SaSun', 'N', 'N', 'N', 'N', 'N', 'Y', 'Y', 'Satruday, Sunday') 
*/ 

;WITH DateAbbrev AS (
    SELECT number, LEFT(DATENAME(dw, number - 2), 3) AS abbrev 
    FROM master..spt_values 
    WHERE type = 'P' 
     AND number BETWEEN 1 AND 7 
) 
SELECT SSS_DOWID, DateAbbrev.number AS DayOfWeek 
FROM SSS_DOW 
UNPIVOT (Flag FOR dow IN ([Mon], [Tue], [Wed], [Thu], [Fri], [Sat], [Sun])) AS pvt 
INNER JOIN DateAbbrev 
    ON DateAbbrev.abbrev = dow 
WHERE Flag = 'Y' 
    AND SSS_DOWID IN (28, 41, 44) 

/* 
DROP TABLE SSS_DOW 
*/ 

Si vous avez déjà une table des abréviations de date, vous pouvez vous joindre à cette place du CTE je créer un ad hoc.

0

Essayez de faire comme ceci et laissez-moi savoir si cela ne fonctionne pas.

DECLARE @strDays table 
(SSS_DOWID int) 

    INSERT INTO @strDays 
select substring(
(SELECT 
case (sun) when 'Y' then ',1' else '' end + 
case (mon) when 'Y' then ',2' else '' end + 
case (tue) when 'Y' then ',3' else '' end + 
case (wed) when 'Y' then ',4' else '' end + 
case (thu) when 'Y' then ',5' else '' end + 
case (fri) when 'Y' then ',6' else '' end + 
    case (sat) when 'Y' then ',7' else '' end 
FROM 
    [dbo].SSS_DOW WITH (NOLOCK) 
WHERE 
SSS_DOWID IN (28,41,44) ),2,100) 

SELECT * FROM @strDays 
+0

Il n'est pas approprié de demander que les gens votent ou acceptent votre réponse. –