3

我正在尝试创建一个查询,以获取下面的事件打开小时数是我的查询。我正在使用案例陈述,因为它需要考虑到只计算工作日。这是我的总体目标是实际获得那些日子的时间的过程中的一个步骤。因此,例如,如果这些天的天数超过一个计数并乘以 8.. 如果它小于一个,则执行 datediff 小时并获取当天的小时数.. 任何帮助将不胜感激!

但我收到以下错误:

当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。

DECLARE @workdays int
SELECT creationDateTime, 
       closedDateTime,DATEDIFF(dd, creationDateTime, closedDateTime)+1,
       CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
            THEN (
                  SELECT creationDateTime ,closedDateTime, 
                    ((DATEDIFF(dd, creationDateTime, closedDateTime)+1)
                      -(DATEDIFF(wk, creationDateTime, closedDateTime) * 2)
                      -(CASE WHEN DATENAME(dw, creationDateTime)
                        = 'Sunday' THEN 1 ELSE 0 END)
                      -(CASE WHEN DATENAME(dw, closedDateTime) 
                        = 'Saturday' THEN 1 ELSE 0 END)
                  )*8 AS workdayhours
                  FROM table.ofevents where closedDateTime IS NOT NULL) END
FROM table.ofevents where closedDateTime IS NOT NULL
4

2 回答 2

4

正如错误所说,您不能在一个值中选择多个列。执行 select 语句时:

SELECT A, B, C ...

每个表达式A, B, C, 表示要返回的一列数据。integer该列由具有类似ordouble或的数据类型的值组成varchar

所以当你这样做时:

SELECT A, B, (SELECT C, D FROM ...) ...

你在说“我想要一列 As,一列 Bs,和一列......”哎呀。您刚刚破坏了 SQL,因为它不知道如何将多个值放在这样的单个单元格中。(嗯,一些 SQL 变体确实知道如何做到这一点,但并不总是那么简单。)

你可能想要的是:

SELECT A, B, (SELECT C FROM ...), (SELECT D FROM ...) etc.

所以,这意味着这样的事情:

declare @workdays int


 SELECT creationDateTime

      , closedDateTime

      , DATEDIFF(dd, creationDateTime, closedDateTime)+1

      , CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
          THEN 
           (SELECT creationDateTime
              as workdayhours
              from table.ofevents where closedDateTime IS NOT NULL)
          END

      , CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
          THEN 
           (SELECT closedDateTime
              as workdayhours
              from table.ofevents where closedDateTime IS NOT NULL)
          END

      , CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)
          THEN ( (DATEDIFF(dd, creationDateTime, closedDateTime)+1 )
                -(DATEDIFF(wk, creationDateTime, closedDateTime) * 2)
                -(CASE WHEN DATENAME(dw, creationDateTime) = 'Sunday' THEN 1 ELSE 0 END)
                -(CASE WHEN DATENAME(dw, closedDateTime) = 'Saturday' THEN 1 ELSE 0 END))*8
              as workdayhours
              from table.ofevents where closedDateTime IS NOT NULL)
          END

   FROM table.ofevents where closedDateTime IS NOT NULL

看看每个子查询如何只选择一个

但是,我仍然不明白为什么您需要选择“creationDateTime”和“closeDateTime”,因此您可能可以删除这些列。

最后一条建议,因为我经常在人们的 SQL 相关问题中看到这一点。非常深刻、非常彻底地问问自己,为什么要让 SQL 做某事。你为什么输入:

   (SELECT creationDateTime ,closedDateTime, 
     ( (DATEDIFF(dd, creationDateTime, closedDateTime)+1 )

为什么会creationDateTime出现在前面closeDateTime,是什么意思?SQL 是一种声明性语言,您写下您的意图,数据库的工作就是生成与您的意图相匹配的数据。这与大多数命令式编程语言不同,如 C。在 C 中,你写下如何做某事。对于大多数理解命令式语言的人来说,这使得理解 SQL 变得非常困难。所以,问问自己,你为什么要创建那个子查询,你的目标是什么?

如果我的回答不够,请编辑您的问题以阐明您希望结果查询的样子。这是非常重要的。如果你不告诉我们你期望查询返回什么,你怎么能期望告诉数据库,或者期望我们告诉你如何告诉数据库呢?

于 2013-07-31T19:45:39.407 回答
3

我认为您可以摆脱子查询,其他一切都会起作用:

declare @workdays int


SELECT creationDateTime ,closedDateTime,DATEDIFF(dd, creationDateTime, closedDateTime)+1,

CASE WHEN (DATEDIFF(dd, creationDateTime, closedDateTime)+1 > 1)

THEN 

  (( (DATEDIFF(dd, creationDateTime, closedDateTime)+1 )
  -(DATEDIFF(wk, creationDateTime, closedDateTime) * 2)
  -(CASE WHEN DATENAME(dw, creationDateTime) = 'Sunday' THEN 1 ELSE 0 END)
  -(CASE WHEN DATENAME(dw, closedDateTime) = 'Saturday' THEN 1 ELSE 0 END))*8

  as workdayhours

END


FROM table.ofevents where closedDateTime IS NOT NULL

我“按原样”保留了您的工作日时间逻辑。

于 2013-07-31T19:57:40.610 回答