使用GROUP BY和MAX进行MySQL查询,返回错误结果

时间:2019-10-29 13:09:29

标签: mysql

我的查询结果很奇怪:

SELECT 
  veicoli_ID, 
  MAX(DataScadenzaRevisione) AS mmax, 
  EsitoPositivo AS StatoUltimaRevisione 
FROM revisioni_veicolo 
GROUP BY veicoli_ID 
HAVING StatoUltimaRevisione = 1

我在这里创建了小提琴:

http://sqlfiddle.com/#!9/4d97cd/1

为什么StatoUltimaRevisione列始终返回true?我认为ID 20和26必须为假。

已执行(HAVING StatoUltimaRevisione = 1):

veicoli_ID     mmax     StatoUltimaRevisione
6           2019-08-01  true
7           2018-04-09  true
20          2018-12-01  false
26          2020-10-01  false
44          2019-09-01  true
45          2020-05-01  true

3 个答案:

答案 0 :(得分:1)

根据documentation,您得到的结果是“正确” 。
但是,您尝试应用的逻辑无效。
您在SELECT列表中拥有EsitoPositivo子句中未包含的GROUP BY列,并且该列未进行汇总(与MINMAX,{{ 1}}等),您认为为SUM列返回的值将是带有EsitoPositivo的行中的值,但不能保证
为什么?因为:

  

...服务器可以从每个组中自由选择任何值,因此除非   它们是相同的,选择的值是不确定的...

因此为MAX(DataScadenzaRevisione)选择的值是它所属组中的任何值。

您必须通过将表联接到仅返回EsitoPositivoveicoli_ID的查询来更改查询的逻辑:

MAX(DataScadenzaRevisione)

或使用SELECT r.veicoli_ID, g.mmax, r.EsitoPositivo AS StatoUltimaRevisione FROM revisioni_veicolo r INNER JOIN ( SELECT veicoli_ID, MAX(DataScadenzaRevisione) AS mmax FROM revisioni_veicolo GROUP BY veicoli_ID ) g ON g.veicoli_ID = r.veicoli_ID AND g.mmax = r.DataScadenzaRevisione

NOT EXISTS

请参见demo
结果:

SELECT 
  r.veicoli_ID, 
  r.DataScadenzaRevisione AS mmax, 
  r.EsitoPositivo AS StatoUltimaRevisione 
FROM revisioni_veicolo r 
WHERE NOT EXISTS (
  SELECT 1 FROM revisioni_veicolo
  WHERE veicoli_ID = r.veicoli_ID AND DataScadenzaRevisione > r.DataScadenzaRevisione
)

答案 1 :(得分:0)

尝试一下:

SELECT veicoli_ID
       , MAX(DataScadenzaRevisione) AS mmax
       , case when min(EsitoPositivo) = 0 then 'false'
         else 'true'
         end StatoUltimaRevisione
FROM revisioni_veicolo
GROUP BY veicoli_ID

DEMO

答案 2 :(得分:0)

发现结果:

 SELECT a.veicoli_ID, a.EsitoPositivo, a.DataScadenzaRevisione
FROM revisioni_veicolo a
INNER JOIN (
    SELECT veicoli_ID, MAX(DataScadenzaRevisione) AS MaxDataScadenzaRevisione
    FROM revisioni_veicolo
    GROUP BY veicoli_ID
) b ON a.veicoli_ID = b.veicoli_ID AND a.DataScadenzaRevisione = b.MaxDataScadenzaRevisione