简体   繁体   English

分组时打印哪一列找到具有相同值的多行?

[英]Which column is printed when grouping by finds multiple rows with same value?

在此处输入图片说明

So my question is, if i group by ContacType on this resultset i will get 3 rows, one for TMV, one for TEL and another for EML, but if i print the ContactValue column which one will be printed for TMV and TEL?所以我的问题是,如果我在这个结果集上按 ContacType 分组,我将得到 3 行,一个用于 TMV,一个用于 TEL,另一个用于 EML,但是如果我打印 ContactValue 列,哪一个将打印用于 TMV 和 TEL? Is it the first occurrence for each one?342222 and 33333?Or is there an specific order when Grouping ?是每个人第一次出现吗?342222 和 33333?还是分组时有特定的顺序?

In order for the query you are describing to be valid ANSI SQL, you would have to specify an aggregate function to be used against the ContactValue column.为了使您所描述的查询成为有效的 ANSI SQL,您必须指定一个要用于ContactValue列的聚合函数。 For example, if you wanted the alphabetically earliest contact value for each type, you could write:例如,如果您想要每种类型按字母顺序排列的最早联系人值,您可以编写:

SELECT
    ContactType,
    MIN(ContactValue) AS ContactValueFirst
FROM yourTable
GROUP BY
    ContactType;

MySQL happens to be unique in that it has a server mode called ONLY_FULL_GROUP_BY which, when disabled, would actually allow the following query: MySQL 的独特之处在于它有一个名为ONLY_FULL_GROUP_BY的服务器模式,当禁用时,它实际上允许以下查询:

SELECT
    ContactType,
    ContactValue
FROM yourTable
GROUP BY
    ContactType;

Your actual question may be which contact value would get returned in this case.您的实际问题可能是在这种情况下会返回哪个联系人值。 Best practice is to not even rely on this server mode loophole, but rather to always use a query along the lines of the first one which I gave.最佳实践是甚至不要依赖这个服务器模式漏洞,而是始终按照我给出的第一个方法使用查询。 One main reason for this is that if you write your code assuming ONLY_FULL_GROUP_BY mode is disabled, if that mode is ever enabled, your existing code could break.一个主要原因是,如果您编写代码时假设ONLY_FULL_GROUP_BY模式被禁用,如果该模式被启用,您现有的代码可能会中断。

From the documentation for ONLY_FULL_GROUP_BY mode:来自ONLY_FULL_GROUP_BY模式的 文档

If ONLY_FULL_GROUP_BY is disabled ... the server is free to choose any value from each group, so unless they are the same, the values chosen are nondeterministic , which is probably not what you want.如果 ONLY_FULL_GROUP_BY 被禁用……服务器可以自由地从每个组中选择任何值,所以除非它们相同,否则选择的值是不确定的,这可能不是你想要的。 Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause.此外,添加 ORDER BY 子句不会影响从每个组中选择值。

You should not run queries that produce nondeterministic results.您不应运行产生不确定结果的查询。 If you do, you risk creating bugs in your code.如果这样做,您可能会在代码中产生错误。

In practice, the current versions of MySQL return the first value read in index order when you execute a query like the one you show.实际上,当您执行像您显示的查询时,当前版本的 MySQL 会返回按索引顺序读取的第一个值。 The value returned depends on the index the query uses.返回的值取决于查询使用的索引。 This can change, depending on which indexes you add or drop from your table, or it can change depending on the optimizer's choice of which index to read.这可能会发生变化,具体取决于您从表中添加或删除哪些索引,或者它可能会根据优化器选择读取哪个索引而发生变化。

Future versions of MySQL might change the implementation. MySQL 的未来版本可能会更改实现。 They are under no obligation to preserve non-standard behavior.他们没有义务保留非标准行为。 So if you try to depend on this "feature," you will get a surprise if you ever upgrade your version of MySQL.所以如果你试图依赖这个“特性”,如果你升级了你的 MySQL 版本,你会得到一个惊喜。 It could lead to bugs in your application that are hard to detect.它可能会导致您的应用程序中出现难以检测的错误。

Also, different SQL database implementations might behave a different way.此外,不同的 SQL 数据库实现可能会有不同的行为方式。 For example, SQLite is the only other database I know that allows these kinds of ambiguous queries, but SQLite returns the last value read in index order.例如,SQLite 是我所知道的唯一允许此类模糊查询的其他数据库,但 SQLite 返回按索引顺序读取的最后一个值。 Why?为什么? Just because of the way they implemented it.只是因为他们实施它的方式。 It's non-standard and arbitrary behavior anyway, so it can't be called wrong.无论如何,这是非标准和任意的行为,因此不能称为错误。

This is why it's a bad idea to create queries that have such variable results.这就是为什么创建具有此类可变结果的查询是一个坏主意的原因。 It can lead to confusing application behavior.它可能会导致令人困惑的应用程序行为。

In all other popular SQL databases (PostgreSQL, Oracle, Microsoft, etc.), it's simply an error to run such queries.在所有其他流行的 SQL 数据库(PostgreSQL、Oracle、Microsoft 等)中,运行此类查询只是一个错误。

It's also an error in the ANSI SQL specification.这也是 ANSI SQL 规范中的一个错误。 When ONLY_FULL_GROUP_BY is disabled, MySQL allows usage that is not valid SQL.ONLY_FULL_GROUP_BY被禁用时,MySQL 允许使用无效的 SQL。 You should try to avoid it.你应该尽量避免它。


Re your comment on Tim's answer:重新评论蒂姆的回答:

The idea here is, Entity BBB will have priority, so grouping by ContactType i would first want all contacts of BBB entity, now in this case only AAA has an email(EML) so i know that would return normally.这里的想法是,实体 BBB 将具有优先权,所以按 ContactType 分组我首先想要 BBB 实体的所有联系人,现在在这种情况下只有 AAA 有电子邮件(EML),所以我知道它会正常返回。 The issue is that you have phone(TEL) and mobile (TMV) in both entities(BBB and AAA) but i would need the BBB ones in this case.问题是您在两个实体(BBB 和 AAA)中都有电话(TEL)和手机(TMV),但在这种情况下我需要 BBB。 That's i first ordered by BBB first and AAA second, thinking that Group By would return first occurrence of the ContactValue associated with the group by column (ContactType).那是我首先按 BBB 排序,然后按 AAA 排序,认为 Group By 将返回与 group by 列 (ContactType) 关联的 ContactValue 的第一次出现。

This sounds like it should be solved with a window function, not GROUP BY.这听起来应该用窗口函数来解决,而不是 GROUP BY。 You'll have to use MySQL 8.0 or later for this.为此,您必须使用 MySQL 8.0 或更高版本。

WITH OrderedContacts AS (
  SELECT Entity, ContactType, ContactValue,
    ROW_NUMBER() OVER (PARTITION BY ContactType ORDER BY Entity DESC) AS rownum
  FROM Contacts
)
SELECT * FROM OrderedContacts WHERE rownum = 1

The ORDER BY Entity DESC puts BBB first, if one exists for a given contact type. ORDER BY Entity DESC将 BBB 放在首位,如果给定联系人类型存在 BBB。 Then AAA follows.然后是AAA。 So if there is a BBB, it gets row number 1. If there is no BBB, then AAA gets row number 1. This way only one row per contact type is returned, and BBB naturally takes "priority".所以如果有 BBB,它得到第 1 行。如果没有 BBB,那么 AAA 得到第 1 行。这样每个联系人类型只返回一行,BBB 自然会获得“优先级”。

If you use min or max for contact value then it will return min or max value for that contact type.If you want to do order by contacttype ordering .just write order by clause for it如果您使用 min 或 max 作为联系值,那么它将返回该联系类型的最小值或最大值。

Example : In this wil order by contacttype in ascending order示例:在此将按联系人类型升序排列

SELECT ContactType, MIN(ContactValue) AS ContactValueFirst FROM yourTable GROUP BY ContactType Order by 1 SELECT ContactType, MIN(ContactValue) AS ContactValueFirst FROM yourTable GROUP BY ContactType Order by 1

Output:输出:

Contacttype Contactvalue EML China@port.com TEL 914444444 TMV. Contacttype Contactvalue EML China@port.com TEL 914444444 TMV。 312222 312222

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM