SQL 2005 SELECT CASE<列>陈述

发布于 2024-07-13 12:32:38 字数 1208 浏览 4 评论 0原文

我真的很感谢这方面的帮助,我严重陷入困境。 基本上我有一个

如下所示的表:

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 的表?

I would really appreciate help with this, I am seriously stuck. Basically I have a table that

looks like this:

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.

What I need to do is to convert the values in this table to a table that contains only the

corresponding numbers for days of the week,
e.g, 1 for Sunday, 2 for Monday, 3 for Tuesday, etc., all the way until 8 for Sunday.

SO I have this little bit of 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

Which works fine for individual days, EXCEPT day combinations. So in this case, when I pass in

28 (Wed), 41 (Fri), and 44 (SaSun), I get 4 (perfect), 6 (perfect), and 17 (oh crap - should be

1 and 7, separately).

Can anyone please help me restructure my SQL so I get a table containing 1, 4, 6, and 7 instead

of 4, 6, 17?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

桃酥萝莉 2024-07-20 12:32:38

听起来你需要取消旋转。

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

Sounds like you need an 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
难得心□动 2024-07-20 12:32:38
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);
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);
梦冥 2024-07-20 12:32:38

在我看来,您正在引用您的数字:

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

因此,使用“+”时您得到的是连接而不是加法。 这就是为什么你的答案是 17。

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

It looks to me like you are quoting your numbers:

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

So what you are getting when using '+' is concatenation instead of addition. That is why you are getting 17 as your answer.

As for breaking it up into two separate answers in a column, you may need to try one of the answers listed here.

月亮是我掰弯的 2024-07-20 12:32:38

在 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。

In SQL Server 2005, you can use the explicit 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
*/

If you already have a table of date abbreviations, you can join to that instead of the ad hoc CTE I used to create one.

千仐 2024-07-20 12:32:38

尝试制作七个插入语句:

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.

Try making seven insert statements:

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.
笑,眼淚并存 2024-07-20 12:32:38

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

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

Try doing like this and let me know if this does not work.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文