sqlserver-Case

sqlserver-Case,sql,sql-server,case,Sql,Sql Server,Case,在SQL Server 2016中,我对上表进行了查询,以获得最高值可能是这样的?将最终表格输出作为内联视图引用: 如果您将表解压到单个状态列中,这似乎会更容易。下面是一个交叉应用的方法: 以下语句为您提供从status4到status1的最高状态,等于或低于900 对于其中一个sts_id=1,没有这样的状态,因此返回NULL 但是你说,你想要100个sts_id=1。所以,我不确定您是否想要一个聚合,并且每个stsuid只需要一行 如果您这样做,一种可能的方法是首先使用联合获取每个STU i

在SQL Server 2016中,我对上表进行了查询,以获得最高值可能是这样的?将最终表格输出作为内联视图引用:


如果您将表解压到单个状态列中,这似乎会更容易。下面是一个交叉应用的方法:


以下语句为您提供从status4到status1的最高状态,等于或低于900

对于其中一个sts_id=1,没有这样的状态,因此返回NULL

但是你说,你想要100个sts_id=1。所以,我不确定您是否想要一个聚合,并且每个stsuid只需要一行

如果您这样做,一种可能的方法是首先使用联合获取每个STU id的所有状态。在这里可以消除重复项,就像我们稍后使用GROUP BY一样,过滤小于或等于900的值,然后按STU id分组并获取每个STU id的最大值

我会使用apply和max,但如下所示:

sts_id | status
-----: | -----:
     1 |    100
     2 |    200
     3 |    600
     4 |    900
这可能与Aaron的答案基本相同。然而,有一个根本的区别。聚合发生在一行中,最多有4个值。这应该很快。将聚合放在apply之外意味着需要聚合整个数据,并且当您想要添加列时会有点麻烦


此外,这将返回所有行,即使没有状态满足这些条件。如果您希望在这种情况下过滤一行,那么将where maxstatus not null添加到外部查询。

那么您是否试图获取每个sts_id的maxstatus,而忽略status>900的情况?您发布的查询没有做到您所说的,使整个问题对我来说非常不清楚。如果表的第二行的status4值为200…您是否仍希望为ID 1返回100?我看到的最大问题是表的设计。您的重复组违反了1NF,这使得查询具有挑战性。您的请求毫无意义!下一个值是什么意思。表中没有已排序的数据,SQL Server不保证按特定顺序返回行,除非使用order BY。我们怎么知道999是100之前还是之后?!?如果你想得到最小值,那么你可以使用最小值,但是如果没有命令,就没有下一个命令:-@AaronDietz。关键是在外部查询中不需要聚合来聚合行中的值。但我看到样本数据有重复的STU id。根据合理但我不认为OP希望每个STU id有一行的明确假设,您的答案是正确的。感谢您的回复,Gordon。我删除了我的评论,因为其中有一半是对打字错误的评论,但对于未来的观众,我问如果一个外部的最大值。。。需要GROUP BY来删除重复项。
SELECT DISTINCT 
   sts_id
 , CASE
       WHEN status1 > 0 AND status2 = 0 THEN status1
       WHEN status2 > 900 AND status3 = 0 THEN status1
       WHEN status2 BETWEEN 1 AND 900 AND status3 = 0 THEN status2
       WHEN status3 > 900 AND status4 = 0 THEN status2
       WHEN status3 BETWEEN 1 AND 900 AND status4 = 0 THEN status3
       WHEN status4 > 900 THEN status3 WHEN status4 BETWEEN 1 AND 900 THEN status4
       ELSE status1
   END AS 'status'
FROM test
| sts_ID | status |
|--------|--------|
|  1     |  100   |
|  1     |  999   |
|  2     |  200   |
|  3     |  600   |
|  4     |  800   |
|  4     |  900   |
        SELECT sts_id, MAX(status)
        FROM
        (
        SELECT sts_id, status, CASE WHEN status > 900 THEN 0 ELSE 1 END AS status_above_900
        FROM inline_view
        ) a1
        WHERE status_above_900 = 1
        GROUP BY sts_id
SELECT sts_id, MAX(status) MaxStatus
FROM TEST
CROSS APPLY (VALUES (status1), 
                    (status2), 
                    (status3), 
                    (status4)
            ) A (status)
WHERE STATUS <= 900
GROUP BY sts_id
STS_ID  MaxStatus
1       100
2       200
3       600
4       900
SELECT sts_id,
       CASE
         WHEN status4 > 0
              AND status4 <= 900 THEN
           status4
         WHEN status3 > 0
              AND status3 <= 900 THEN
           status3
         WHEN status2 > 0
              AND status2 <= 900 THEN
           status2
         WHEN status1 > 0
              AND status1 <= 900 THEN
           status1
       END status
       FROM test;
sts_id | status
-----: | -----:
     1 |
     1 |    100
     2 |    200
     3 |    600
     4 |    900
     4 |    800
SELECT sts_id,
       max(status) status
       FROM (SELECT sts_id,
                    status1 status
                    FROM test
                    WHERE status1 <= 900
             UNION
             SELECT sts_id,
                    status2 status
                    FROM test
                    WHERE status2 <= 900
             UNION
             SELECT sts_id,
                    status3 status
                    FROM test
                    WHERE status3 <= 900
             UNION
             SELECT sts_id,
                    status4 status
                    FROM test
                    WHERE status4 <= 900) x
       GROUP BY sts_id;
sts_id | status
-----: | -----:
     1 |    100
     2 |    200
     3 |    600
     4 |    900
SELECT sts_id, v.MaxStatus
FROM TEST CROSS APPLY
     (SELECT MAX(status) as MaxStatus
      FROM (VALUES (status1), 
                   (status2), 
                   (status3), 
                   (status4)
           ) v(status)
      WHERE STATUS <= 900
     ) v;