在 'group by'、select 之后的非空值和特定列中的最大值
After 'group by', select value that is not null and from highest value in a specific column
我有一个 TEST_RESULT
table 有一个连续的测试结果。
version| test_id | test_result
---------------------------------------
v1 | 53 | fail
v2 | 53 | fail
v3 | 53 | success
---------------------------------------
v1 | 60 | unprocessable
v2 | 60 | null
v3 | 60 | null
测试 53
在 v1、v2 上失败,但在 v3
上它被修补并因此成功。
测试60
在v1
中是unprocessable
,在以后的版本v2
和v3
.
中没有执行
最后的table我想摆脱这个看起来像这样:
test_id | final_result
---------------------------------------
53 | success
60 | unprocessable
如果值不为空,final_result
将显示最高版本的 test_result
值。如果该值为空,它将显示下一个最高版本的 test_result
等等。 (请注意,无论版本是否有测试结果,它总会有版本行)。
我能够使用 ROW_NUMBER()
对具有相同 test_id
的行进行排序,但有点迷茫我们如何从版本中实现“非空 test_result
值那是尽可能高的部分。这样的逻辑在后端代码中实现更好吗?我想不出适合这个的 SQL 运算符。
SELECT
test_id,
ROW_NUMBER() OVER (PARTITION BY test_Id ORDER BY version DESC) AS row_num
FROM TEST_RESULT
GROUP BY test_id
你不能只排除 WHERE test_result is NOT NULL
的记录。
SELECT test_id, test_result
FROM (
SELECT
test_id,
test_result,
ROW_NUMBER() OVER (PARTITION BY test_id ORDER BY version DESC) AS row_num
FROM TEST_RESULT
WHERE test_result is NOT NULL
)
WHERE row_num = 1
可能不是最好的解决方案,但它有效:-)
WITH T as (
SELECT test_id,
max(version) OVER (PARTITION BY test_id ORDER BY version DESC) as version
FROM test_truc
WHERE test_result IS NOT NULL
OR test_result='fail'
GROUP BY test_id,
version)
SELECT DISTINCT T.*,
test.test_result
FROM T
JOIN test_truc test ON test.version = T.version
AND test.test_id = T.test_id
您可以使用 window 函数。关键是将带有值的测试结果放在 NULL
值之前:
SELECT tr.*
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY test_Id ORDER BY (case when test_result IS NOT NULL then 1 else 2 end), version DESC) AS seqnum
FROM TEST_RESULT tr
) tr
WHERE seqnum = 1;
请注意 returns table 中的所有 test_Id
,即使所有结果都是 NULL
。
我有一个 TEST_RESULT
table 有一个连续的测试结果。
version| test_id | test_result
---------------------------------------
v1 | 53 | fail
v2 | 53 | fail
v3 | 53 | success
---------------------------------------
v1 | 60 | unprocessable
v2 | 60 | null
v3 | 60 | null
测试 53
在 v1、v2 上失败,但在 v3
上它被修补并因此成功。
测试60
在v1
中是unprocessable
,在以后的版本v2
和v3
.
最后的table我想摆脱这个看起来像这样:
test_id | final_result
---------------------------------------
53 | success
60 | unprocessable
如果值不为空,final_result
将显示最高版本的 test_result
值。如果该值为空,它将显示下一个最高版本的 test_result
等等。 (请注意,无论版本是否有测试结果,它总会有版本行)。
我能够使用 ROW_NUMBER()
对具有相同 test_id
的行进行排序,但有点迷茫我们如何从版本中实现“非空 test_result
值那是尽可能高的部分。这样的逻辑在后端代码中实现更好吗?我想不出适合这个的 SQL 运算符。
SELECT
test_id,
ROW_NUMBER() OVER (PARTITION BY test_Id ORDER BY version DESC) AS row_num
FROM TEST_RESULT
GROUP BY test_id
你不能只排除 WHERE test_result is NOT NULL
的记录。
SELECT test_id, test_result
FROM (
SELECT
test_id,
test_result,
ROW_NUMBER() OVER (PARTITION BY test_id ORDER BY version DESC) AS row_num
FROM TEST_RESULT
WHERE test_result is NOT NULL
)
WHERE row_num = 1
可能不是最好的解决方案,但它有效:-)
WITH T as (
SELECT test_id,
max(version) OVER (PARTITION BY test_id ORDER BY version DESC) as version
FROM test_truc
WHERE test_result IS NOT NULL
OR test_result='fail'
GROUP BY test_id,
version)
SELECT DISTINCT T.*,
test.test_result
FROM T
JOIN test_truc test ON test.version = T.version
AND test.test_id = T.test_id
您可以使用 window 函数。关键是将带有值的测试结果放在 NULL
值之前:
SELECT tr.*
FROM (SELECT tr.*,
ROW_NUMBER() OVER (PARTITION BY test_Id ORDER BY (case when test_result IS NOT NULL then 1 else 2 end), version DESC) AS seqnum
FROM TEST_RESULT tr
) tr
WHERE seqnum = 1;
请注意 returns table 中的所有 test_Id
,即使所有结果都是 NULL
。