2012-03-25 50 views
0

在下面的代码中,我主要在做我想做的事情,我正在查询属性表,该表通过会场属性表链接到“场地”表,以提供多对多。如何使用此代码查询同一个表两次(保留GROUP_CONCAT)?

我这样做是为了提高在单个场地页面上显示大型列表时的性能,其中我使用工厂来加载场地对象。到目前为止,这个新通话为我节省了很多时间。

首先我想知道为什么我必须使用DISTINCT和GROUP_CONCAT来避免在a.name下的每个场所显示多个值?我没有看到它加入了两次?

我的第二个挑战是检索属性表中保存的评估值,与GROUP_CONCAT返回值分开。 (我把表结构放在查询的下面)。该评级在GROUP_CONCAT(a.name)值内返回,但每个场所只有一个,我需要在select语句内的单独列(如a.rating)中显示它。我应该在场地表中保留评分值,如果它不容易检索 - 但我有兴趣了解MYSQL能做什么,而且我的技术水平相当基本。

谢谢你的时间。

SELECT v.venue_id, v.name, v.suburb, v.venue_email, v.venue_phone, GROUP_CONCAT(DISTINCT a.name) AS attributes, v.review_count, vi.image_thumb_path 
FROM venues AS v 
LEFT JOIN venue_attribute AS va ON v.venue_id = va.venue_id 
LEFT JOIN attribute AS a ON a.att_id = va.attribute_id 
LEFT JOIN venue_review AS vr ON vr.venue_id = v.venue_id 
LEFT JOIN venue_image AS vi ON vi.venue_id = v.venue_id 
WHERE v.status = 1 
GROUP BY v.name; 

Table attribute 
=============== 
att_id, type, name, abbreviation, synonyms, description, scope 
--------------- 
att_id   int(11) PK 
type    enum('transport','purpose','parking','site_control','authorisations','permissions','facilities','rating') 
name    varchar(255) 
abbreviation  varchar(32) 
synonyms   varchar(255) 
description  mediumtext 
scope   enum('global') 
+0

如果一个场地只有一个属性值,但场地和属性之间存在一对多关系,哪一行是评级?他们全部? – Ami 2012-03-25 10:32:47

+0

@Ami,我认为我的问题的这个子集回答你的问题? “我正在查询一个属性表,通过一个场地表属性表连接到'场地'表格,给出了多对多的” – SaminOz 2012-03-25 12:04:40

+0

答案是? – Ami 2012-03-25 12:30:00

回答

1

对于你的第二个挑战,我认为解决的办法是让2加入到attribute表,就像一个如下:

SELECT v.venue_id, v.name, v.suburb, v.venue_email, v.venue_phone, GROUP_CONCAT(DISTINCT a.name) AS attributes, v.review_count, vi.image_thumb_path, a1.name as rating 
FROM venues AS v 
LEFT JOIN venue_attribute AS va ON v.venue_id = va.venue_id 
LEFT JOIN attribute AS a ON a.att_id = va.attribute_id 
LEFT JOIN attribute AS a1 ON a1.att_id = va.attribute_id AND a1.type = 'rating' 
LEFT JOIN venue_review AS vr ON vr.venue_id = v.venue_id 
LEFT JOIN venue_image AS vi ON vi.venue_id = v.venue_id 
WHERE v.status = 1 
GROUP BY v.name; 

上面的查询应该给你的单独评级结果集中的列。

现在对于您的第一个问题,您不必在GROUP_CONCAT中使用DISTINCT,除非同一场地中可能有多个具有相同名称的属性。如果对于一个给定的场地,永远不可能有2个或更多具有相同名称的属性,则可以安全地避免DISTINCT。

希望它有帮助!

+0

感谢您的帮助。我已经标记了你,因为这对我很有帮助,我不知道我可以用这种方式将“where”添加到联接中 - 但是,a1.name AS等级的列正在返回所有调用的NULL值。这段代码可能解释了为什么“如果在LEFT JOIN的ON或USING部分右表没有匹配的行,所有列都设置为NULL的行用于右表”。但是,有值我可以通过在查询的WHERE部分使用“AND a1.type ='rating'”来证明它 - 这明显限制了查询。 – SaminOz 2012-03-25 12:24:29

+0

如果在type =“rating”的属性中有行,它应该反映在结果集中。顺便说一下,你对LEFT JOIN的理解是正确的。有一个条件'v.status = 1';因此对于状态为1的场所,可能没有“评级”属性。请您验证一下吗? – Abhay 2012-03-25 12:40:34

相关问题