使用DISTINCT时发生了什么?

时间:2012-04-10 12:29:27

标签: 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 |
|        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 |
+-----------+----------+----------+

我的目的是获取third_id字段排序data的列表。现在,我为此运行了以下查询。

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 |
+----------+
|        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必须在24之后,因为我在data字段上订购。我究竟做错了什么?或者我必须采取不同的策略。

注意: 这种情况发生在我的项目中。此处提供的表不属于原始数据库。它由我创建来解释问题。原始表包含数千行。 如果您想试验数据,我正在插入数据库转储:

--
-- 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);

4 个答案:

答案 0 :(得分:3)

您可能想要做类似

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

min(data)max(data)或其他。

答案 1 :(得分:2)

执行SELECT DISTINCT要求数据库对列中的值进行排序,因为这是查找不同值的最有效方法。据我所知ORDER BY不包含在查询中输出的列的子句不受尊重(SQL SERVER将不接受查询),因为它不清楚它的意思是什么没有参加的东西。

答案 2 :(得分:2)

您可以使用子查询 -

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;

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

答案 3 :(得分:1)

之前我遇到过这个问题。我终于想出了一个简单的解决方案,几乎看起来太简单了。您需要使用子查询作为选择查询的列。在那个子查询中,您将按日期进行排序。当您在JOIN之前使用ORDER BY进行单个查询时,所有操作都会发生。您想先订购,所以请使用子查询。 http://nathansnoggin.blogspot.com/2009/04/select-distinct-with-order-by.html