【问题标题】:How to use DISTINCT in VIEWS correctly如何在 VIEWS 中正​​确使用 DISTINCT
【发布时间】:2016-12-14 11:19:25
【问题描述】:

我有两个表,我想从中加入一些列,以便为我的 java/hibernate 应用程序提供一个视图。它看起来像这样:

CREATE VIEW customer_contacts AS cc
SELECT DISTINCT ON (cust.id) cust.id
  cust.company
  cust.zip
  ...
  con.name
  con.forename
  ...
FROM contacts con
LEFT JOIN customer cust ON con.customer = cust.id
ORDER BY cust.id

到目前为止一切顺利。很简单。 如果我在视图上进行选择,例如:

SELECT * 
FROM cc
WHERE name ilike '%schult%'

我得到 13 个结果

如果我直接使用视图语句进行相同的查询

SELECT DISTINCT ON (cust.id) cust.id
  cust.company
  cust.zip
  ...
  con.name
  con.forename
  ...
FROM contacts con
LEFT JOIN customer cust ON con.customer = cust.id
WHERE name ilike '%schult%'
ORDER BY cust.id

我得到了 75 个结果! 我发现是 DISTINCT 破坏了结果。但是为什么呢?

又该如何正确使用呢?

【问题讨论】:

  • 请显示您正在运行的“相同查询”的确切 SQL 文本。
  • 嗨彼得,我澄清了我的问题,我已经写了直接声明。
  • 但是您在第二个查询中忘记了条件WHERE name ilike '%schult%'...
  • 没错!但是现在

标签: postgresql hibernate select view distinct


【解决方案1】:

您的查询(基于视图和直接)具有不同的应用条件顺序:

  • 直接查询搜索%shult%,然后应用distinct on
  • 视图应用distinct on,然后搜索%shult%

您知道distinct on 的工作原理吗? 它为给定的属性选择第一行(如果未定义正确的排序,则可能不确定)并保留其他属性。

例如:

假设我们有一个id=1 的客户和两个连接的联系人,一个是name='Schultz',一个是name='Schmidt'。 现在基于视图的选择将应用 distinct on 并选择具有某些联系人的客户(第一个,在这种情况下不确定),然后将应用 name ilike '%schult%' - 可能会发生 Schultz 将被 distinct on 删除。


推荐阅读:

https://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-DISTINCT

【讨论】:

  • 谢谢。您的第一点很清楚,我在 postgre Doc 中找到了它。第二个没有。但我的问题仍然存在:我怎样才能正确地做到这一点。我的意思是,如果没有视图,我如何获得我想要的结果?我正在使用 Hibernate,不想使用查询。这就是我想要使用视图的原因。
  • 顺便说一句。在这种非常特殊的情况下,结果将是相同的,因为没有重复项。所以顺序应该不重要。在其他查询中是可能的。
  • 我不明白:“没有重复”。如果没有重复,您的两个查询都将返回相同的数据。
  • 好吧,在这种情况下,当我添加这个“where-clause (where name ilike '%schulte%'”时,会有不同的结果,这正是问题所在。两个查询返回不同的结果!但是当我尝试例如“where city ilike '%Berlin%') 结果是一样的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-23
相关资源
最近更新 更多