SQL 使用 where 条件查询第二大值
SQL query for second largest value with a where condition
我有一个 table,其中包含步骤 ID 和居民 ID。我想编写一个查询来查找特定居民的第二大步骤 ID。
google 示例中使用 max 的查询没有 where 子句。
试过这个:
SELECT DISTINCT(step_action_id)
FROM step_table where resident_id =219
ORDER BY step_action_id DESC limit 2,1;
Table:
Step_Action_id REsident_id
800 218
801 218
911 218
857 218
856 219
858 219
我期望的结果是 856。但我收到以下错误,
Error: ILLEGAL USE OF KEYWORD LIMIT. TOKEN SKIP OPTIMIZE FOR FETCH , EXCEPT MINUS UNION <END-OF-STATEMENT> WAS EXPECTED. SQLCODE=-199, SQLSTATE=42601, DRIVER=3.59.81
SQLState: 42601
ErrorCode: -199
Error: THE CURSOR SQL_CURLH200C1 IS NOT IN A PREPARED STATE. SQLCODE=-514, SQLSTATE=26501, DRIVER=3.59.81
SQLState: 26501
ErrorCode: -
您可以使用 ROW_NUMBER()
:
SELECT step_action_id
FROM (
SELECT step_action_id, ROW_NUMBER() OVER(ORDER BY step_action_id DESC) AS rn
FROM (SELECT DISTINCT step_action_id
FROM step_table
WHERE resident_id = 219
) AS s
) AS s2
WHERE rn = 2;
ROW_NUMBER() 工作得很好,但您还应该知道 DB2 使用 "FETCH FIRST" 而不是限制 "restrict" 返回的行数。所以你可以用子查询得到 2,然后颠倒顺序得到第二个。像这样:
SELECT step_action_id
FROM (
SELECT DISTINCT step_action_id
FROM step_table
WHERE resident_id =219
ORDER BY step_action_id DESC
FETCH FIRST 2 ROWS ONLY
)
ORDER BY step_action_id ASC
FETCH FIRST 1 ROWS ONLY
如果步骤 ID 不同,您可以只使用 OFFSET
和 FIRST FIRST 1 ROW ONLY
:
SELECT step_action_id
FROM step_table
WHERE resident_id = 219
ORDER BY step_action_id DESC
OFFSET 1 ROWS
FETCH FIRST 1 ROW ONLY;
如果它们不明显,只需添加一个GROUP BY
或SELECT DISTINCT
:
SELECT step_action_id
FROM step_table
WHERE resident_id = 219
GROUP BY step_action_id
ORDER BY step_action_id DESC
OFFSET 1 ROWS
FETCH FIRST 1 ROW ONLY;
谢谢大家让我知道解决这个问题的各种方法。我使用以下查询解决了问题
SELECT max(step_action_id) FROM step_table as p WHERE p.step_action_id < (SELECT max(t.step_action_id) FROM step_table 作为 t 其中 t.residentId = 219) 和 p.residentId = 219";
我有一个 table,其中包含步骤 ID 和居民 ID。我想编写一个查询来查找特定居民的第二大步骤 ID。
google 示例中使用 max 的查询没有 where 子句。 试过这个:
SELECT DISTINCT(step_action_id)
FROM step_table where resident_id =219
ORDER BY step_action_id DESC limit 2,1;
Table:
Step_Action_id REsident_id
800 218
801 218
911 218
857 218
856 219
858 219
我期望的结果是 856。但我收到以下错误,
Error: ILLEGAL USE OF KEYWORD LIMIT. TOKEN SKIP OPTIMIZE FOR FETCH , EXCEPT MINUS UNION <END-OF-STATEMENT> WAS EXPECTED. SQLCODE=-199, SQLSTATE=42601, DRIVER=3.59.81
SQLState: 42601
ErrorCode: -199
Error: THE CURSOR SQL_CURLH200C1 IS NOT IN A PREPARED STATE. SQLCODE=-514, SQLSTATE=26501, DRIVER=3.59.81
SQLState: 26501
ErrorCode: -
您可以使用 ROW_NUMBER()
:
SELECT step_action_id
FROM (
SELECT step_action_id, ROW_NUMBER() OVER(ORDER BY step_action_id DESC) AS rn
FROM (SELECT DISTINCT step_action_id
FROM step_table
WHERE resident_id = 219
) AS s
) AS s2
WHERE rn = 2;
ROW_NUMBER() 工作得很好,但您还应该知道 DB2 使用 "FETCH FIRST" 而不是限制 "restrict" 返回的行数。所以你可以用子查询得到 2,然后颠倒顺序得到第二个。像这样:
SELECT step_action_id
FROM (
SELECT DISTINCT step_action_id
FROM step_table
WHERE resident_id =219
ORDER BY step_action_id DESC
FETCH FIRST 2 ROWS ONLY
)
ORDER BY step_action_id ASC
FETCH FIRST 1 ROWS ONLY
如果步骤 ID 不同,您可以只使用 OFFSET
和 FIRST FIRST 1 ROW ONLY
:
SELECT step_action_id
FROM step_table
WHERE resident_id = 219
ORDER BY step_action_id DESC
OFFSET 1 ROWS
FETCH FIRST 1 ROW ONLY;
如果它们不明显,只需添加一个GROUP BY
或SELECT DISTINCT
:
SELECT step_action_id
FROM step_table
WHERE resident_id = 219
GROUP BY step_action_id
ORDER BY step_action_id DESC
OFFSET 1 ROWS
FETCH FIRST 1 ROW ONLY;
谢谢大家让我知道解决这个问题的各种方法。我使用以下查询解决了问题
SELECT max(step_action_id) FROM step_table as p WHERE p.step_action_id < (SELECT max(t.step_action_id) FROM step_table 作为 t 其中 t.residentId = 219) 和 p.residentId = 219";