2013-06-03 102 views
4

我有3个表:videoscategoriesvideo_categories咨询加盟查询

videos,我有ID,标题等领域。 在categories,我有id和名字。 在video_categories中,我有id,video_id和category_id。

一个视频可以有多个类别。所以video_categories表就是这样的。

id video_id category_id 
1 1   1 
2 1   2 
3 1   3 

如果我想要一个视频列表并显示它们的类别,哪一个会是首选?

  1. 通过PHP,调用1查询获取所有视频,然后循环查询以获取每个视频的类别,并通过另一个查询获取类别名称。如果桌子很大,这会很慢,对吧?

  2. 通过MySQL的连接(需在此帮助)。如果我将加入视频留给video_categories,则会有同样video_id的3个结果。我可以使用GROUP BY或SELECT DISTINCT来获得唯一的结果,但我现在如何获取类别的名称?

我预期的结果将是这样的:

id title categories 
1 Video1 pop, rock, jazz 
+0

我不认为你的问题与非规范化,本身做的。正如您所描述的,您的模式已完全标准化,这意味着它没有冗余数据。你可以通过添加'categories'列到'videos'表,在其中你将存储的类别名称的逗号spearated字符串非规范化它(例如,“流行,摇滚,爵士”),然后用冗余保持同步数据在'categories'和'video_categories'表中。就目前而言,您的问题实际上只是询问如何优化您的连接技术,可以使用'group_concat'方法来完成,正如其他人所说的。 –

+0

是的,我感到困惑。我一定认为非规范化是规范化的逆过程,它是读取和显示规范化的模式。我已编辑标题以避免混淆 – Henson

回答

3

对于选项2,使用GROUP_CONCAT。这将是确定

SELECT v.id, v.title, GROUP_CONCAT(c.name) 
FROM videos v 
INNER JOIN video_categories vc ON vc.video_id = v.id 
INNER JOIN categories c ON vc.category_id = c.id 
GROUP BY v.id, v.title 

对于Group_Concat()功能,是默认的分隔符。这就是为什么我不在这里使用它。

+0

不知道GROUP_CONCAT。谢谢! – Henson

+0

不客气。当我第一次听说这个功能时,同样的事情发生在我身上。真正有用的功能。 – sarwar026

+0

GROUP_CONCAT会在将多个结果分组在一起后将您切断。在这里我没有看到它发生,但是我已经在大约第200次分组结果后停止了连接。 –

3

猜你的其他列的名字..

SELECT v.video_id, v.title, GROUP_CONCAT(c.category_name SEPARATOR ', ') 
FROM videos v 
LEFT JOIN video_categories vc ON vc.video_id = v.video_id 
LEFT JOIN categories c ON c.category_id = vc.category_id 
GROUP BY v.video_id, v.title 
+0

次要的事情 - 这是分隔符,不应该有一个'SEPARATOR'之前的逗号:'GROUP_CONCAT(c.category_name SEPARATOR',')'。 –

+0

@EdGibbs谢谢,正在输入内存。 – Kermit

+0

如何将此语句转换为codeigniter? – Ambrose