MySQL - 从一个表中选择所有内容,但只选择第二个表中的第一个匹配值

时间:2014-01-13 01:10:42

标签: mysql sql select

我在MySQL中创建查询感觉有点生疏。我以为我可以解决这个问题,但我没有运气,四处搜寻并没有导致任何类似的事情......

基本上,我有两张桌子。我想从一个表和第二个表中的匹配行中选择所有内容。但是,我只想从第二个表中得到第一个结果。我希望这是有道理的。

daily_entries表中的行是唯一的。每天会有一排,但可能不是每天都有。第二个表notes包含许多行,每个行都与daily_entries中的 ONE 行相关联。

以下是我的表格的例子;

表一

mysql> desc daily_entries;

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| eid      | int(11)      | NO   | PRI | NULL    | auto_increment |
| date     | date         | NO   |     | NULL    |                |
| location | varchar(100) | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

表二

mysql> desc notes;
+---------+---------+------+-----+---------+----------------+
| Field   | Type    | Null | Key | Default | Extra          |
+---------+---------+------+-----+---------+----------------+
| task_id | int(11) | NO   | PRI | NULL    | auto_increment |
| eid     | int(11) | NO   | MUL | NULL    |                |
| notes   | text    | YES  |     | NULL    |                |
+---------+---------+------+-----+---------+----------------+

我需要做的是从notes中选择所有条目,只有daily_entries的一个结果。

以下是我希望它的外观示例:

+----------------------------------------------+---------+------------+----------+-----+
| notes                                        | task_id | date       | location | eid |
+----------------------------------------------+---------+------------+----------+-----+
| Another note                                 |       3 | 2014-01-02 | Home     |   2 |
| Enter a note.                                |       1 | 2014-01-01 | Away     |   1 |
| This is a test note. To see what happens.    |       2 |            | Away     |   1 |
| Testing another note                         |       4 |            | Away     |   1 |
+----------------------------------------------+---------+------------+----------+-----+
4 rows in set (0.00 sec)

以下是我目前的查询:

SELECT notes.notes, notes.task_id, daily_entries.date, daily_entries.location, daily_entries.eid
FROM daily_entries
LEFT JOIN notes ON daily_entries.eid=notes.eid
ORDER BY daily_entries.date DESC

以下是我查询的外观示例:

+----------------------------------------------+---------+------------+----------+-----+
| notes                                        | task_id | date       | location | eid |
+----------------------------------------------+---------+------------+----------+-----+
| Another note                                 |       3 | 2014-01-02 | Home     |   2 |
| Enter a note.                                |       1 | 2014-01-01 | Away     |   1 |
| This is a test note. To see what happens.    |       2 | 2014-01-01 | Away     |   1 |
| Testing another note                         |       4 | 2014-01-01 | Away     |   1 |
+----------------------------------------------+---------+------------+----------+-----+
4 rows in set (0.00 sec)

起初我以为我可以简单GROUP BY daily_entries.date,但是只返回每个匹配集的第一行。甚至可以这样做吗?我非常感谢有人能提供的任何帮助。在我的查询结束时使用Limit显然将其限制为我指定的值,但将其应用于预期的所有内容。

3 个答案:

答案 0 :(得分:1)

基本上,您的查询没有任何问题。我相信它正是您所需要的,因为它返回您想要的数据。您无法看到它正在复制您应该查看的daily_entries,就像它返回所有notes及其关联的daily_entry一样。

当然,你可以实现你在问题中描述的内容(已经有一个解决这个问题的答案),但在你这样做之前要三思而后行,因为这样的嵌套查询只会给你的数据库服务器增加很多明显的性能开销。

我建议您使用一个LEFT JOIN(这是您需要的)尽可能简单地查询,然后让消费者应用程序操纵数据并按照他们需要的方式呈现。

答案 1 :(得分:1)

按功能使用mysql的非标准组:

SELECT n.notes, n.task_id, de.date, de.location, de.eid
FROM notes n
LEFT JOIN (select * from 
  (select * from daily_entries ORDER BY date DESC) x 
  group by eid) de ON de.eid = n.eid

答案 2 :(得分:0)

您需要使用最后一行的显式过滤来执行这些查询。此示例使用join执行此操作:

SELECT n.notes, n.task_id, de.date, de.location, de.eid
FROM daily_entries de LEFT JOIN
     notes n
     ON de.eid = n.eid LEFT JOIN
     (select n.eid, min(task_id) as min_task_id
      from notes n
      group by n.eid
     ) nmin
     on n.task_id = nmin.min_task_id
ORDER BY de.date DESC;