sqlserver-Case
在SQL Server 2016中,我对上表进行了查询,以获得最高值可能是这样的?将最终表格输出作为内联视图引用: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
如果您将表解压到单个状态列中,这似乎会更容易。下面是一个交叉应用的方法:
以下语句为您提供从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;