使用 hsql db 时查询得到 "invalid order by" 而 Mysql 没有(结果只能是一列)
Query gets "invalid order by" when using hsql db while Mysql does not ( result must be one column only)
虽然此查询在 MySQL 数据库中 运行 正常:
SELECT DISTINCT user_id
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
ORDER BY user_login_time DESC
LIMIT 10 OFFSET 0
当我尝试通过 HSQL 运行 相同的查询时,出现此错误:
nested exception is java.sql.SQLSyntaxErrorException: invalid ORDER BY expression in statement [SELECT DISTINCT user_id FROM table_name WHERE user_name IN (:userNameList) AND user_type IN ('client','vip') ORDER BY user_login_time desc LIMIT 10 OFFSET 0]
这个问题的解决方案需要我更改查询:在 HSQL 中我们必须 select 按列排序。没有它,我们会收到此错误。
SELECT DISTINCT user_id, user_login_time
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
ORDER BY user_login_time DESC
LIMIT 10 OFFSET 0
但是这个解决方案 return 是两列而不是一列。
通过使用 JDBCTAmplate,我找到了一种方法 return 只有一列
String query = "SELECT DISTINCT user_id , user_login_time FROM table_name WHERE user_name IN (:userNameList) AND user_type IN ('client','vip') ORDER BY user_login_time DESC LIMIT 10 OFFSET 0";
List<String> userIds = new ArrayList<String>();
List<String> userIdList = List.of("12345667", "123443235");
Map<String, Object> sqlParameterSource = new HashMap<>();
sqlParameterSource.put("userNameList", userIdList);
userIds = namedParamJDBCTemplate.query(query, new MapSqlParameterSource(sqlParameterSource), new ResultSetExtractor<List>() {
@Override
public List extractData(ResultSet resultSet) throws SQLException, DataAccessException {
List<String> listRes = new ArrayList<String>();
while (resultSet.next()) {
listRes.add(resultSet.getString(USER_ID));
}
return listRes;
}
});
这个解决方案允许我通过 HSQL 运行 查询,结果仍然只得到一列。
像这样的查询 returns 只有 user_id 列
SELECT user_id FROM
( SELECT DISTINCT user_id, user_login_time
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
ORDER BY user_login_time DESC
LIMIT 10 OFFSET 0 )
如果一个用户多次登录,MySQL查询returns一行用户,其中一次登录时间用于下单,可能不是该用户最后一次登录时间.
最好使用GROUP BY来确保结果一致:
SELECT user_id
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
GROUP BY user_id
ORDER BY MAX(user_login_time) DESC
LIMIT 10 OFFSET 0
虽然此查询在 MySQL 数据库中 运行 正常:
SELECT DISTINCT user_id
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
ORDER BY user_login_time DESC
LIMIT 10 OFFSET 0
当我尝试通过 HSQL 运行 相同的查询时,出现此错误:
nested exception is java.sql.SQLSyntaxErrorException: invalid ORDER BY expression in statement [SELECT DISTINCT user_id FROM table_name WHERE user_name IN (:userNameList) AND user_type IN ('client','vip') ORDER BY user_login_time desc LIMIT 10 OFFSET 0]
这个问题的解决方案需要我更改查询:在 HSQL 中我们必须 select 按列排序。没有它,我们会收到此错误。
SELECT DISTINCT user_id, user_login_time
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
ORDER BY user_login_time DESC
LIMIT 10 OFFSET 0
但是这个解决方案 return 是两列而不是一列。
通过使用 JDBCTAmplate,我找到了一种方法 return 只有一列
String query = "SELECT DISTINCT user_id , user_login_time FROM table_name WHERE user_name IN (:userNameList) AND user_type IN ('client','vip') ORDER BY user_login_time DESC LIMIT 10 OFFSET 0";
List<String> userIds = new ArrayList<String>();
List<String> userIdList = List.of("12345667", "123443235");
Map<String, Object> sqlParameterSource = new HashMap<>();
sqlParameterSource.put("userNameList", userIdList);
userIds = namedParamJDBCTemplate.query(query, new MapSqlParameterSource(sqlParameterSource), new ResultSetExtractor<List>() {
@Override
public List extractData(ResultSet resultSet) throws SQLException, DataAccessException {
List<String> listRes = new ArrayList<String>();
while (resultSet.next()) {
listRes.add(resultSet.getString(USER_ID));
}
return listRes;
}
});
这个解决方案允许我通过 HSQL 运行 查询,结果仍然只得到一列。
像这样的查询 returns 只有 user_id 列
SELECT user_id FROM
( SELECT DISTINCT user_id, user_login_time
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
ORDER BY user_login_time DESC
LIMIT 10 OFFSET 0 )
如果一个用户多次登录,MySQL查询returns一行用户,其中一次登录时间用于下单,可能不是该用户最后一次登录时间.
最好使用GROUP BY来确保结果一致:
SELECT user_id
FROM table_name
WHERE user_name IN (:userNameList)
AND user_type IN ('client','vip')
GROUP BY user_id
ORDER BY MAX(user_login_time) DESC
LIMIT 10 OFFSET 0