2014-01-13 120 views
0

我在MySQL中创建查询感觉有点生疏。我以为我可以解决这个问题,但我没有运气,四处搜寻不会导致任何类似的...MySQL - 从一个表中选择所有内容,但只在第二个表中选择第一个匹配值

基本上,我有两个表。我想从一个表中选择一切,并从第二个表中选择匹配的行。但是,我只想从第二个表获得第一个结果。我希望这是有道理的。

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

下面是我的表格的例子;

表一

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,但是这回ONL y每个匹配集的第一行。这甚至可以完成?我将不胜感激任何人可以提供的帮助。在我的查询结束处使用Limit显然将其限制为我指定的值,但将其应用于所需的所有内容。

+2

通常这些类型的格式的改进在应用层实现(例如,报告工具有一个选项,“禁止重复值”) – cha

+0

你能确认你想要第二张表中最近的一行(如果存在)? – Bohemian

回答

1

基本上没有什么不对您的查询。我相信这正是你需要的,因为它会返回你想要的数据。你不能看看它是否复制了你应该看到的daily_entries,好像它将返回所有notes及其关联的daily_entry

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

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

+0

谢谢。我接受了您的建议并保留了当前编写的查询。这些数据正在被馈入一个动态网页,所以我只是在cgi脚本的表格中的那一列中执行删除重复数据。不知道为什么我没有这样做,因为这是一个两分钟的修复。另外两个答案也似乎返回所有的数据,像我原来的查询? – canadmos

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; 
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 
相关问题