【问题标题】:SUM result value repeats even with case statement即使使用 case 语句,SUM 结果值也会重复
【发布时间】:2012-11-04 18:15:29
【问题描述】:

我使用 posgresql 作为数据库,使用 java 作为 hibernate 的编程语言。我的问题是这个查询:

select cast(sum(CASE WHEN p.nropack > 0 THEN p.nropack ELSE 0 END) as integer),
cast(sum(CASE WHEN p.nropack < 0 THEN p.nropack ELSE 0 END) as integer),
cast(p.fechareg as date) 
from pronostico p 
inner join aeropuerto a on (a.idaeropuerto=p.idaeropuerto)
inner join ciudad c on (a.idciudad=c.idciudad)
inner join pais ps on (ps.idpais=c.idpais)
inner join continente ct on (ct.idcontinente=ps.idcontinente)
where c.idciudad=105
group by cast (p.fechareg as date);

结果我得到:

sum;sum;fechareg 
30;-15;"2012-11-15"

但是当我在我的程序中使用它时:

public ArrayList<RepKardex> listarKardex(int ciud){  
    ciud=105; 
    ArrayList<RepKardex> listaKardex = new ArrayList<>();
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = session.beginTransaction();        
    String q = "select cast(sum( case when p.nropack > 0 then p.nropack ELSE 0 end ) as integer), "
            + "cast(sum( case when p.nropack < 0 then p.nropack ELSE 0 end ) as integer), "
            + "cast(p.fechareg as date) "
            + "from Pronostico p "
            + "inner join Aeropuerto a on (p.idaeropuerto = a.idaeropuerto) "
            + "inner join Ciudad c on (a.idciudad = c.idciudad) "
            + "inner join Pais ps on (c.idpais = ps.idpais) "
            + "inner join Continente ct on (ct.idcontinente = ps.idcontinente) "
            + "where c.idciudad = :ciud "
            + "group by cast(p.fechareg as date) ";                    
    Query query = session.createSQLQuery(q);        
    query.setInteger("ciud", ciud);
    List lista = query.list();        
    Iterator iter = lista.iterator(); 
    while (iter.hasNext()) {    
        Object[] row = (Object[]) iter.next();            
        if (row!=null){
            System.out.println("entrantes : "+(Integer)row[0]); 
            System.out.println("salientes : "+(Integer)row[1]); 
            RepKardex rep = new RepKardex((int)row[0],(int)row[1],(Date)row[2]);              
            listaKardex.add(rep);
        }

    }

    tx.commit();
    session.close();

    return listaKardex;
} 

打印出来

entrantes: 30
salida:    30

即使我在查询中使用 case 语句,有人可以帮我弄清楚为什么它会重复正数吗?提前致谢。

【问题讨论】:

  • 我不熟悉java,但是如果查询返回您期望的值,可能问题出在您处理返回值的方式上,您可以尝试将行的内容作为一个整体打印而不是 row[0] 或 row[1] 看看结果如何?
  • 我看到一些系统在存在多个具有相同名称(总和)的列时会感到困惑,但我不知道这是否是导致您的问题的原因。您能否尝试看看当您明确命名列时会发生什么? select cast(sum(CASE WHEN p.nropack &gt; 0 THEN p.nropack ELSE 0 END) as integer) as sum1, ... as sum2, ...
  • @hvd 谢谢!,这解决了问题。我当然不知道为什么会发生这种情况,但我认为是因为没有列的明确名称它认为这两个 sum 函数是一个,也许?。好吧,再次感谢您和其他帮助我的人。

标签: java sql hibernate postgresql sum


【解决方案1】:

您可以使用LEAST and GREATEST 简化您的查询:

SELECT sum(GREATEST(p.nropack, 0))::int AS entrantes
      ,sum(LEAST(p.nropack, 0))::int AS salida
      ,p.fechareg::date AS fechareg
from   pronostico  p 
JOIN   aeropuerto  a ON a.idaeropuerto = p.idaeropuerto
JOIN   ciudad      c ON c.idciudad = a.idciudad
JOIN   pais       ps ON ps.idpais = c.idpais
JOIN   continente ct ON ct.idcontinente = ps.idcontinente
where  c.idciudad = 105
GROUP  BY p.fechareg::date;

除此之外,它看起来还不错。我认为第二列不可能返回正数。这里肯定有其他问题。

编辑:

Comment by @hvd 帮助发现客户端代码似乎被相同的列名混淆(两个总和列默认为"sum")。显式列别名似乎可以解决此问题。

【讨论】:

  • 谢谢。这简化了查询,尽管当我将它放入程序时强制转换不起作用,因为休眠使用字符“:”来调用查询中的参数。我用的是最大的和最少的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 2012-11-12
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
相关资源
最近更新 更多