Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在JPA上选择DISTINCT_Java_Sql_Jpa_Jpql - Fatal编程技术网

Java 在JPA上选择DISTINCT

Java 在JPA上选择DISTINCT,java,sql,jpa,jpql,Java,Sql,Jpa,Jpql,我有一个关于货币的表格(有6行,ID,国家,货币名称,字母代码,数字代码,小单位) 我需要获取的一些数据,我的“纯”SQL查询如下所示: select distinct currency_name, alphabetic_code, numeric_code from currency where ALPHABETIC_CODE IN ('USD','EUR','JPY','GBP') order by currency_name; SELECT DISTINCT c.currencyN

我有一个关于货币的表格(有6行,ID,国家,货币名称,字母代码,数字代码,小单位)

我需要获取的一些数据,我的“纯”SQL查询如下所示:

select distinct currency_name, alphabetic_code, numeric_code 
from currency 
where ALPHABETIC_CODE IN ('USD','EUR','JPY','GBP') 
order by currency_name;
SELECT DISTINCT c.currencyName, c.alphabeticCode, c.numericCode
FROM Currency c 
WHERE c.alphabeticCode IN ('EUR','GBP','USD','JPY') 
ORDER BY c.currencyName
SELECT p.id AS id1_0_0_,
       pc.id AS id1_1_1_,
       p.created_on AS created_2_0_0_,
       p.title AS title3_0_0_,
       pc.post_id AS post_id3_1_1_,
       pc.review AS review2_1_1_,
       pc.post_id AS post_id3_1_0__
FROM   post p
LEFT OUTER JOIN
       post_comment pc ON p.id=pc.post_id
WHERE
       p.title='High-Performance Java Persistence eBook has been released!'

-- Fetched the following Post entity identifiers: [1, 1]
它返回一个包含所需数据的4行表。到目前为止,一切顺利

现在我必须将其转换为我们的JPA xml文件,问题就开始了。我试图得到的查询如下:

select distinct currency_name, alphabetic_code, numeric_code 
from currency 
where ALPHABETIC_CODE IN ('USD','EUR','JPY','GBP') 
order by currency_name;
SELECT DISTINCT c.currencyName, c.alphabeticCode, c.numericCode
FROM Currency c 
WHERE c.alphabeticCode IN ('EUR','GBP','USD','JPY') 
ORDER BY c.currencyName
SELECT p.id AS id1_0_0_,
       pc.id AS id1_1_1_,
       p.created_on AS created_2_0_0_,
       p.title AS title3_0_0_,
       pc.post_id AS post_id3_1_1_,
       pc.review AS review2_1_1_,
       pc.post_id AS post_id3_1_0__
FROM   post p
LEFT OUTER JOIN
       post_comment pc ON p.id=pc.post_id
WHERE
       p.title='High-Performance Java Persistence eBook has been released!'

-- Fetched the following Post entity identifiers: [1, 1]
这将返回一个列表,其中每个国家都有一行货币(就好像查询中没有“DISTINCT”一样)。我不知道为什么。因此,问题是:

1) 如何进行此查询以返回“纯”SQL所提供的内容

2) 为什么这个查询似乎忽略了我的“DISTINCT”子句?这里有些东西我遗漏了,但我不明白。发生了什么事,我没有得到什么

编辑:嗯,这越来越奇怪了。不知何故,JPA查询按预期工作(返回4行)。我尝试过这个(因为我需要更多信息):

ID似乎把一切都搞乱了,因为从查询中删除它会返回4行表。加括号是没用的


顺便说一句,我们正在使用eclipse链接。

您遇到的问题是当您试图检索列列表时(
c.currencyName,c.alphalcoccode,c.numericCode,c.minorUnit,c.id)

  • distinct在select子句中提到的整个列上运行
我相信“id”列对于db表中的每个记录都是唯一的,因此您有可能在其他列中获得重复项
(c.currencyName、c.alphalcoccode、c.numericCode、c.minorUnit)

因此,在您的示例中,DISTINCT在整行上运行,而不是在 特定列。如果要获取唯一的名称,请仅选择该名称 专栏

如果您想在多个列上运行distinct,您可以执行以下操作,例如使用GROUP BY来使用
c.currencyName,c.Alphaccode

SELECT DISTINCT c.currencyName, c.alphabeticCode, c.numericCode,c.id
FROM Currency c 
WHERE c.alphabeticCode IN ('EUR','GBP','USD','JPY') GROUP BY c.currencyName, c.alphabeticCode
ORDER BY c.currencyName

为了回答您的问题,您编写的JPQL查询很好:

SELECT DISTINCT c.currencyName, c.alphabeticCode, c.numericCode
FROM Currency c 
WHERE c.alphabeticCode IN ('EUR','GBP','USD','JPY') 
ORDER BY c.currencyName
它应该转换为您期望的SQL语句:

select distinct currency_name, alphabetic_code, numeric_code 
from currency 
where ALPHABETIC_CODE IN ('USD','EUR','JPY','GBP') 
order by currency_name;
根据基础JPQL或Criteria API查询类型,[
DISTINCT
][1]在JPA中有两种含义

标量查询 对于返回标量投影的标量查询,如以下查询:

List<Integer> publicationYears = entityManager
.createQuery(
    "select distinct year(p.createdOn) " +
    "from Post p " +
    "order by year(p.createdOn)", Integer.class)
.getResultList();

LOGGER.info("Publication years: {}", publicationYears);
实体查询 对于实体查询,
DISTINCT
具有不同的含义

不使用
DISTINCT
,类似以下查询:

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "left join fetch p.comments " +
    "where p.title = :title", Post.class)
.setParameter(
    "title", 
    "High-Performance Java Persistence eBook has been released!"
)
.getResultList();

LOGGER.info(
    "Fetched the following Post entity identifiers: {}", 
    posts.stream().map(Post::getId).collect(Collectors.toList())
);
但是,对于每个关联的
post_注释
行,结果集中的父
post
记录都是重复的。因此,
Post
实体的
列表将包含重复的
Post
实体引用

要消除
Post
实体引用,我们需要使用
DISTINCT

List<Post> posts = entityManager
.createQuery(
    "select distinct p " +
    "from Post p " +
    "left join fetch p.comments " +
    "where p.title = :title", Post.class)
.setParameter(
    "title", 
    "High-Performance Java Persistence eBook has been released!"
)
.getResultList();
 
LOGGER.info(
    "Fetched the following Post entity identifiers: {}", 
    posts.stream().map(Post::getId).collect(Collectors.toList())
);
通过将
DISTINCT
传递给SQL查询,执行计划将执行额外的排序阶段,该阶段会增加开销,而不会带来任何值,因为父子组合总是返回唯一的记录,因为子PK列:

Unique  (cost=23.71..23.72 rows=1 width=1068) (actual time=0.131..0.132 rows=2 loops=1)
  ->  Sort  (cost=23.71..23.71 rows=1 width=1068) (actual time=0.131..0.131 rows=2 loops=1)
        Sort Key: p.id, pc.id, p.created_on, pc.post_id, pc.review
        Sort Method: quicksort  Memory: 25kB
        ->  Hash Right Join  (cost=11.76..23.70 rows=1 width=1068) (actual time=0.054..0.058 rows=2 loops=1)
              Hash Cond: (pc.post_id = p.id)
              ->  Seq Scan on post_comment pc  (cost=0.00..11.40 rows=140 width=532) (actual time=0.010..0.010 rows=2 loops=1)
              ->  Hash  (cost=11.75..11.75 rows=1 width=528) (actual time=0.027..0.027 rows=1 loops=1)
                    Buckets: 1024  Batches: 1  Memory Usage: 9kB
                    ->  Seq Scan on post p  (cost=0.00..11.75 rows=1 width=528) (actual time=0.017..0.018 rows=1 loops=1)
                          Filter: ((title)::text = 'High-Performance Java Persistence eBook has been released!'::text)
                          Rows Removed by Filter: 3
Planning time: 0.227 ms
Execution time: 0.179 ms
带有提示的实体查询\u PASS\u DISTINCT\u THROUGH 为了从执行计划中消除排序阶段,我们需要使用
HINT\u PASS\u DISTINCT\u THROUGH
JPA查询提示:

List<Post> posts = entityManager
.createQuery(
    "select distinct p " +
    "from Post p " +
    "left join fetch p.comments " +
    "where p.title = :title", Post.class)
.setParameter(
    "title", 
    "High-Performance Java Persistence eBook has been released!"
)
.setHint(QueryHints.HINT_PASS_DISTINCT_THROUGH, false)
.getResultList();
 
LOGGER.info(
    "Fetched the following Post entity identifiers: {}", 
    posts.stream().map(Post::getId).collect(Collectors.toList())
);
执行计划将确认我们这次不再有额外的分拣阶段:

Hash Right Join  (cost=11.76..23.70 rows=1 width=1068) (actual time=0.066..0.069 rows=2 loops=1)
  Hash Cond: (pc.post_id = p.id)
  ->  Seq Scan on post_comment pc  (cost=0.00..11.40 rows=140 width=532) (actual time=0.011..0.011 rows=2 loops=1)
  ->  Hash  (cost=11.75..11.75 rows=1 width=528) (actual time=0.041..0.041 rows=1 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 9kB
        ->  Seq Scan on post p  (cost=0.00..11.75 rows=1 width=528) (actual time=0.036..0.037 rows=1 loops=1)
              Filter: ((title)::text = 'High-Performance Java Persistence eBook has been released!'::text)
              Rows Removed by Filter: 3
Planning time: 1.184 ms
Execution time: 0.160 ms

您的JPQ提供者的日志将告诉您它已将JPQL翻译成的SQL。好的,现在我明白了,在运行了更多的测试之后,我将谴责某些查询中的输入错误,因为DISTINCT在SQL和JPA上的表现不同。顺便说一句,GROUPBY子句不起作用。。。我想我暂时把身份证忘了。
Hash Right Join  (cost=11.76..23.70 rows=1 width=1068) (actual time=0.066..0.069 rows=2 loops=1)
  Hash Cond: (pc.post_id = p.id)
  ->  Seq Scan on post_comment pc  (cost=0.00..11.40 rows=140 width=532) (actual time=0.011..0.011 rows=2 loops=1)
  ->  Hash  (cost=11.75..11.75 rows=1 width=528) (actual time=0.041..0.041 rows=1 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 9kB
        ->  Seq Scan on post p  (cost=0.00..11.75 rows=1 width=528) (actual time=0.036..0.037 rows=1 loops=1)
              Filter: ((title)::text = 'High-Performance Java Persistence eBook has been released!'::text)
              Rows Removed by Filter: 3
Planning time: 1.184 ms
Execution time: 0.160 ms