SELECT子句中嵌套子查询触发SQL Error [102][S0001](语法错误靠近')'),该写法是否可行?
解决SELECT子句嵌套子查询的语法错误问题
嘿,我来帮你排查这个SQL的问题~你遇到的SQL Error [102] [S0001]: Sintaxe incorreta próxima a ')'错误,核心是你的嵌套子查询写法违反了SQL的语法规则,而且逻辑上也有小问题,咱们一步步拆解:
错误原因分析
- 标量子查询不能返回多列:你在SELECT列表里嵌套的子查询试图同时返回
ultimo_abastecimento和qtd两个字段,但SELECT子句里的子查询(也就是「标量子查询」)必须只能返回一行一列的单个值——数据库没办法把两个值塞进一个列的位置,这是直接触发语法报错的原因。 - 内层子查询的逻辑冗余且不严谨:你套了两层子查询,但内层的
group by fa.veiculo之后,qtd字段既没被聚合(比如用MAX/MIN)也没出现在GROUP BY里,如果你的数据库开启了严格模式,这本身也会报错;而且你要的是「最新加油记录对应的时间和油量」,这种写法根本拿不到正确的qtd值。
修正方案
方案1:用两个独立的标量子查询(简单直观)
把需要的两个字段拆成两个单独的标量子查询,每个子查询只返回单个值:
SELECT V.NUMERO_PATRIMONIO, P.NOME, S.NOME, V.PLACA, V.MARCA, V.MODELO, V.ANO_FABRICACAO, V.FROTA_TEXTO, V.RENAVAM, V.COMBUSTIVEL, V.BAIXADO, -- 获取该车辆最新的加油时间 (SELECT MAX(fa.data_cadastro) FROM frota_abastecimento fa WHERE fa.veiculo = V.id) AS ultimo_abastecimento, -- 获取对应最新时间的加油量 (SELECT fa.qtd FROM frota_abastecimento fa WHERE fa.veiculo = V.id AND fa.data_cadastro = (SELECT MAX(fa2.data_cadastro) FROM frota_abastecimento fa2 WHERE fa2.veiculo = V.id)) AS qtd FROM FROTA_VEICULO V LEFT JOIN PATRIMONIO_TOMBAMENTO T ON T.PLACA = V.NUMERO_PATRIMONIO and (v.ID_ORGAO = t.id_orgao OR v.ID_ORGAO IS NULL) LEFT JOIN PATRIMONIO_SETOR S ON S.ID_SETOR = T.ID_SETOR LEFT JOIN PATRIMONIO_SETOR P ON P.ID_SETOR = S.ID_PARENTE WHERE 1=1 AND P.ID_SETOR = 8 AND (V.BAIXADO = 0 OR V.BAIXADO IS NULL) ORDER BY P.NOME, S.NOME
方案2:用窗口函数(更高效,推荐)
通过窗口函数给每个车辆的加油记录按时间排序,直接取最新的那一条,避免多次子查询的性能损耗:
SELECT V.NUMERO_PATRIMONIO, P.NOME, S.NOME, V.PLACA, V.MARCA, V.MODELO, V.ANO_FABRICACAO, V.FROTA_TEXTO, V.RENAVAM, V.COMBUSTIVEL, V.BAIXADO, fa.ultimo_abastecimento, fa.qtd FROM FROTA_VEICULO V LEFT JOIN PATRIMONIO_TOMBAMENTO T ON T.PLACA = V.NUMERO_PATRIMONIO and (v.ID_ORGAO = t.id_orgao OR v.ID_ORGAO IS NULL) LEFT JOIN PATRIMONIO_SETOR S ON S.ID_SETOR = T.ID_SETOR LEFT JOIN PATRIMONIO_SETOR P ON P.ID_SETOR = S.ID_PARENTE -- 左连接预处理后的最新加油记录 LEFT JOIN ( SELECT veiculo, data_cadastro AS ultimo_abastecimento, qtd, -- 按车辆分组,按加油时间倒序排序,第一条就是最新记录 ROW_NUMBER() OVER (PARTITION BY veiculo ORDER BY data_cadastro DESC) AS rn FROM frota_abastecimento ) fa ON fa.veiculo = V.id AND fa.rn = 1 WHERE 1=1 AND P.ID_SETOR = 8 AND (V.BAIXADO = 0 OR V.BAIXADO IS NULL) ORDER BY P.NOME, S.NOME
关于你的疑问:SELECT子句里可以用嵌套子查询吗?
当然可以,但必须是标量子查询(返回一行一列)——你原来的写法试图返回多列,这是不允许的。如果需要获取多个字段,要么拆成多个标量子查询,要么像方案2那样用JOIN的方式关联预处理后的子查询结果。
内容的提问来源于stack exchange,提问作者Diego Alves
相关产品推荐
相关产品推荐

