如何处理空值 - JPA / SQL / JPQL

时间:2014-04-20 15:37:15

标签: sql jpa derby jpql

应该很简单,但我现在真的很困惑

我有一个数据库查询:

   public double markingAvg(Marking id) {
        System.out.println("In MarkingAvg");
        System.out.println("id = " + id);
        System.out.println("id = " + id.getId());
        Query m = em.createQuery("SELECT m.markSectionOne, m.markSectionTwo, m.markSectionThree, m.markSectionFour, m.markSectionFive, m.markSectionSix, m.markSectionSeven, m.markSectionEight, m.markSectionNine, m.markSectionTen, m.markSectionEleven, m.markSectionTwelve, m.markSectionThirteen FROM MARKING m WHERE m.id = :id", Double.class);
        m.setParameter("id", id.getId()); // Note the getId()
        System.out.println(m);


        List<Object[]> allMarks = m.getResultList();
        double total = 0.0;
        int count = 0;

        for (Object[] marks : allMarks) {
            for (Object mark : marks) {
                total += Double.parseDouble((String) mark);
                ++count;
            }
        }
        return total / (double) count;
    }

只是获取13列中的值并对其进行平均值,但是当它们中存在空值时它会中断,有没有办法说明是否有任何列的空值返回总数为0?谢谢

3 个答案:

答案 0 :(得分:2)

您可以使用内联条件检查:

    total += Double.parseDouble((String) ((mark==null) ? 0 : mark)));

答案 1 :(得分:1)

您也可以在查询中处理此问题:例如:

ij> CREATE TABLE T(I INT);
ij> INSERT INTO T VALUES 1, 2, 3, NULL;
4 rows inserted/updated/deleted
ij> SELECT * FROM T;
I          
-----------
1          
2          
3          
NULL       

4 rows selected
ij> SELECT (CASE WHEN I IS NULL THEN 0 ELSE I END) FROM T;
1          
-----------
1          
2          
3          
0          

4 rows selected

在您的情况下,计算SQL中的平均值可能更好

ij> SELECT AVG(CAST(I AS DOUBLE)) AS AVERAGE FROM T;
AVERAGE                 
------------------------
2.0                     
WARNING 01003: Null values were eliminated from the argument of a column function.

1 row selected

注意警告。如果你真的希望NULL在平均值中计为0,你必须使用上面提到的CASE表达式。

答案 2 :(得分:0)

将您的查询更改为以下内容:

SELECT NVL(m.markSectionOne,0), 
       NVL(m.markSectionTwo,0), 
       NVL(m.markSectionThree,0), 
       NVL(m.markSectionFour,0), 
       NVL(m.markSectionFive,0), 
       NVL(m.markSectionSix,0), 
       NVL(m.markSectionSeven,0),
       NVL(m.markSectionEight,0),
       NVL(m.markSectionNine,0), 
       NVL(m.markSectionTen,0),
       NVL(m.markSectionEleven,0), 
       NVL(m.markSectionTwelve,0),
       NVL(m.markSectionThirteen,0) 
FROM MARKING m WHERE m.id = :id;