【问题标题】:SQL 2005 SELECT CASE <column> statementSQL 2005 SELECT CASE <column> 语句
【发布时间】:2009-01-31 20:26:58
【问题描述】:

非常感谢您的帮助,我被严重卡住了。基本上我有一张桌子

看起来像这样:

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.

我需要做的是将这个表中的值转换为只包含

的表

一周中的相应数字, 例如,1 代表星期日,2 代表星期一,3 代表星期二,等等,一直到星期日 8 点。

所以我有一点点 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

这适用于个别日子,除了日子组合。所以在这种情况下,当我传入

28(周三)、41(周五)和 44(周六),我得到 4(完美)、6(完美)和 17(哦,废话——应该是

1 和 7,分别)。

谁能帮我重组我的 SQL,以便我得到一个包含 1、4、6 和 7 的表

4、6、17 个?

【问题讨论】:

    标签: sql sql-server case unpivot


    【解决方案1】:

    听起来你需要一个非枢轴。

    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
    

    【讨论】:

      【解决方案2】:
      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);
      

      【讨论】:

        【解决方案3】:

        在我看来你在引用你的数字:

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

        所以当你使用“+”时你得到的是连接而不是加法。这就是为什么你的答案是 17。

        至于将其分成一列中的两个单独答案,您可能需要尝试此处列出的答案之一。

        【讨论】:

          【解决方案4】:

          在 SQL Server 2005 中,您可以使用显式 UNPIVOT

          /*
          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
          */
          

          如果您已经有一个日期缩写表,则可以加入该表,而不是我用来创建的临时 CTE。

          【讨论】:

            【解决方案5】:

            尝试制作七个插入语句:

            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.
            

            【讨论】:

              【解决方案6】:

              尝试这样做,如果这不起作用,请告诉我。

              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
              

              【讨论】:

              • 不适合要求人们投票或接受您的回答。
              猜你喜欢
              • 2014-12-05
              • 2011-08-28
              • 2015-02-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-03-23
              相关资源
              最近更新 更多