Mysql 使用DISTINCT时发生了什么?

Mysql 使用DISTINCT时发生了什么?,mysql,sql,select,distinct,Mysql,Sql,Select,Distinct,这是我的表格和其中包含的数据: Table: first +----------+------+ | first_id | data | +----------+------+ | 1 | 5 | | 2 | 6 | | 3 | 7 | | 4 | 6 | | 5 | 7 | | 6 | 5 | | 7 | 7 | | 8 | 6 |

这是我的表格和其中包含的数据:

Table: first

+----------+------+
| first_id | data |
+----------+------+
|        1 |    5 |
|        2 |    6 |
|        3 |    7 |
|        4 |    6 |
|        5 |    7 |
|        6 |    5 |
|        7 |    7 |
|        8 |    6 |
|        9 |    5 |
|       10 |    7 |
+----------+------+

Table: second
+-----------+----------+----------+
| second_id | first_id | third_id |
+-----------+----------+----------+
|         1 |        1 |        2 |
|         2 |        2 |        3 |
|         3 |        3 |        4 |
|         4 |        4 |        2 |
|         5 |        5 |        3 |
|         6 |        6 |        4 |
|         7 |        7 |        2 |
|         8 |        8 |        2 |
|         9 |        9 |        4 |
|        10 |       10 |        4 |
+-----------+----------+----------+
我的目的是获取按
数据
字段排序的
第三个id
的列表。现在,我为此运行了以下查询

SELECT
    third_id, data
FROM 
    first f JOIN second s ON ( s.first_id = f.first_id )
ORDER BY 
    data ASC;
我得到了如下预期的结果

+----------+------+
| third_id | data |
+----------+------+
|        4 |    5 |
|        2 |    5 |
|        4 |    5 |
|        2 |    6 |
|        3 |    6 |
|        2 |    6 |
|        2 |    7 |
|        4 |    7 |
|        4 |    7 |
|        3 |    7 |
+----------+------+
SELECT 
    third_id
FROM 
    first f JOIN second s ON ( s.first_id = f.first_id )
ORDER BY 
    data ASC;
以下查询也按预期工作

+----------+------+
| third_id | data |
+----------+------+
|        4 |    5 |
|        2 |    5 |
|        4 |    5 |
|        2 |    6 |
|        3 |    6 |
|        2 |    6 |
|        2 |    7 |
|        4 |    7 |
|        4 |    7 |
|        3 |    7 |
+----------+------+
SELECT 
    third_id
FROM 
    first f JOIN second s ON ( s.first_id = f.first_id )
ORDER BY 
    data ASC;
有输出

+----------+
| third_id |
+----------+
|        4 |
|        2 |
|        4 |
|        2 |
|        3 |
|        2 |
|        2 |
|        4 |
|        4 |
|        3 |
+----------+
然后我运行了以下命令

SELECT DISTINCT
    third_id
FROM 
    first f JOIN second s ON ( s.first_id = f.first_id )
ORDER BY 
    data ASC;

但是,这里我得到了一个意想不到的结果:

+----------+
| third_id |
+----------+
|        2 |
|        3 |
|        4 |
+----------+
这里,
3
必须在
2
4
之后,因为我是在
数据
字段上排序的。我做错了什么?或者我必须采取不同的策略

注: 这种情况发生在我的项目中。这里提供的表不属于原始数据库。这是我创造的解释这个问题。原始表包含数千行。 如果您想试验数据,我将插入数据库转储:

--
-- Table structure for table `first`
--

CREATE TABLE IF NOT EXISTS `first` (
  `first_id` int(11) NOT NULL AUTO_INCREMENT,
  `data` int(11) NOT NULL,
  PRIMARY KEY (`first_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

--
-- Dumping data for table `first`
--

INSERT INTO `first` (`first_id`, `data`) VALUES
(1, 5),
(2, 6),
(3, 7),
(4, 6),
(5, 7),
(6, 5),
(7, 7),
(8, 6),
(9, 5),
(10, 7);
--
-- Table structure for table `second`
--

CREATE TABLE IF NOT EXISTS `second` (
  `second_id` int(11) NOT NULL AUTO_INCREMENT,
  `first_id` int(11) NOT NULL,
  `third_id` int(11) NOT NULL,
  PRIMARY KEY (`second_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

--
-- Dumping data for table `second`
--

INSERT INTO `second` (`second_id`, `first_id`, `third_id`) VALUES
(1, 1, 2),
(2, 2, 3),
(3, 3, 4),
(4, 4, 2),
(5, 5, 3),
(6, 6, 4),
(7, 7, 2),
(8, 8, 2),
(9, 9, 4),
(10, 10, 4);

你可能想做一些类似的事情

SELECT third_id
FROM first JOIN second USING (first_id)
GROUP BY third_id
ORDER BY aggregatesomething(data)

也就是说
min(data)
max(data)
或任何东西。

执行
选择不同的
需要数据库对列中的值进行排序,因为这是查找不同值的最有效方法。据我所知,
ORDER BY
子句中不包含查询中输出的列,因此不会被接受(SQL SERVER不会接受查询),因为不清楚按未参与的内容排序意味着什么。

您可以使用子查询-

SELECT DISTINCT third_id FROM (
  SELECT
    third_id
  FROM 
    first f JOIN second s ON ( s.first_id = f.first_id )
  ORDER BY 
    data ASC
) t;

它将有助于首先选择和排序所有数据,然后选择不同的值。

我以前遇到过这个问题。我终于想出了一个简单的解决办法,似乎太简单了。您需要将子查询用作select查询的列。在该子查询中,您将按日期进行排序。当您使用ORDER BY在单个查询中完成所有操作时,将发生在联接之前。您想先下单,所以使用子查询

但是,这里我得到了一个意外的结果:“-这不是意外的。如果我是sql,我会拒绝这个
orderby
子句,但是
mysql
对它的容忍度是出了名的。你想按哪个
data
排序?@MitchWheat问题的作者没有预料到这一点,因此从这个意义上说,这是出乎意料的。他正在按隐藏列排序,并想知道为什么在最终查询中不保留该顺序。为了澄清,您希望4,2,3,根据数据顺序选择不同的值?这里不是正数,但我认为distinct select会根据distinct字段自动对字段进行排序,否则查询效率会低很多。如果您希望第三个ID的列表按数据字段排序,为什么要使用distinct呢?为什么在查询中有这样的连接?连接似乎未使用,因为第一个id和数据都在第一个表中。我看不出有理由忽略排序依据,因为它未被选中。这里的问题是模糊性。在mysql中,选择DISTINCT不排序值,表示mysql的一个怪癖是它允许您编写查询,因为它没有任何意义。在
中选择DISTINCT
可以完全忽略与
数据相关的所有信息。查询引擎应该告诉你,你问的不是一个合理的问题,然后就把它炸掉。相反,它选择混淆人们。@user317290该页面根本没有这样说。执行
SELECT DISTINCT
不会显式地对值进行排序(也就是说,不能保证它们会被排序),但实际上它通常会对它们进行排序,因为这是从列表中删除重复项的最有效方法(如果找到正确的索引,它可能会找到更好的方法)。@TheMouthofaCow it说,“DISTINCT和GROUP BY之间的区别在于DISTINCT不会导致行排序。在MySQL中,GROUP BY确实会导致排序。“如果运行Devart的查询,它确实会得到“4,2,3”的结果,这意味着MySQL在这里不使用排序方法来删除重复项。使用
min(数据)
奏效了。虽然@Devart的答案也奏效了,但我还是接受了这个答案,因为它看起来更自然、更简单。只是查了一下。我想两者都应该奏效,尽管我会说@Devart的有点脆弱。从理论上讲,如果你没有
ORDER BY
你的输出是无序的,即使这个理论经常不同rom练习。