我有一个数据库,其中有关于小马的详细信息,另一个有关联系人(所有者和繁殖者)的详细信息,还有其他几个小参数表(颜色,县,区号等)。为了给我一个现有小马配置文件列表,给出各种详细信息,我使用以下查询:
SELECT *
FROM profiles
INNER JOIN prm_breedgender
ON profiles.ProfileGenderID = prm_breedgender.BreedGenderID
LEFT JOIN contacts
ON profiles.ProfileOwnerID = contacts.ContactID
INNER JOIN prm_breedcolour
ON profiles.ProfileAdultColourID = prm_breedcolour.BreedColourID
ORDER BY profiles.ProfileYearOfBirth ASC $limit
在上面的示例中,'profiles'表是我的主表(保存Ponies信息),'contacts'在重要性保持中排名第二,因为它具有所有者和育种者信息。较小的参数表可以通过其prm_前缀来标识。上面的查询工作正常,但我想做更多。
第一个重要问题是我希望按性别对结果进行分组:种马,马雷斯,阉割......我用过<< GROUP BY prm_breedgender.BreedGender>>或<< GROUP BY ProfileBreedGenderID>>在我的ORDER BY行之前,但只返回我所有可用配置文件中的两个结果。我已经阅读了这个,并且显然需要重新组织我的查询以在我的主要SELECT子句中容纳GROUP。然而,如何做到这一点,让我感到困惑。这里一步一步的帮助将是非常棒的。
作为对上述内容的进一步说明 - 您可能已经注意到我的查询结尾处的$ limit var。这是分页,我想保留的功能。但我不认为这是一个问题。
我的第二个问题更多是组织问题。您可以在此处查看我从联系人表格中提取所有者信息的位置:
LEFT JOIN contacts
ON profiles.ProfileOwnerID = contacts.ContactID
我可以补充另一条规定:
AND profiles.ProfileBreederID = contacts.ContactID
意图是能够列出小马的所有者和饲养员,其中任何一个的信息都可用。我不知道如何回应这些信息,因为$ row ['ContactName']可能适用于所有者或饲养员的能力。
这是一个简单地运行两个查询而不是一个查询的情况吗?为第一次运行查询分配变量$ foo,然后只运行另一个单独的查询并为这些结果分配$ bar?或者是否有更聪明的方法在一个查询中完成所有操作(例如$ row ['ContactName'] First-iteration,$ row ['ContactName'] Second-iteration)?这里的建议将非常感激。
就是这样!我尽量保持清醒,并且非常感谢您提供的任何帮助或建议。提前谢谢。
################################################## ########################编辑我的查询目前是Cularis和Symcbean提供的混合:
SELECT *
FROM (
profiles
INNER JOIN prm_breedgender
ON profiles.ProfileGenderID = prm_breedgender.BreedGenderID
LEFT JOIN contacts AS owners
ON profiles.ProfileOwnerID = owners.ContactID
INNER JOIN prm_breedcolour
ON profiles.ProfileAdultColourID = prm_breedcolour.BreedColourID
)
LEFT JOIN contacts AS breeders
ON profiles.ProfileBreederID = breeders.ContactID
ORDER BY prm_breedgender.BreedGender ASC, profiles.ProfileYearOfBirth ASC $limit
只要按照我的预期安排结果,即按年龄和性别安排,它就能正常运作。但是,我似乎无法让别名'与联系人查询(饲养员和所有者)相关。没有显示错误,也没有任何所有者或饲养员。任何进一步的澄清将非常感激。
P.S。我通过Symcbean的例子删除了给最终LEFT JOIN的别名,因为我无法得到生成的ORDER BY语句为我工作 - 我自己的错,我确定。尽管如此,它现在可以正常工作,尽管这可能是导致联系人查询问题的原因。
答案 0 :(得分:2)
GROUP
表示在一组条目上使用聚合函数。我想你想要的是性别顺序:
ORDER BY prm_breedgender.BreedGender ASC, profiles.ProfileYearOfBirth ASC $limit
这将输出彼此相邻的所有种马等。
要获得育种者联系,您还需要使用别名再次加入联系人表格:
LEFT JOIN contacts AS owners
ON profiles.ProfileOwnerID = owners.ContactID
LEFT JOIN contacts AS breeders
ON profiles.ProfileBreederID = breeders.ContactID
答案 1 :(得分:2)
为了进一步扩展@cularis所说的内容,group by用于聚合到最低级别的“分组”标准。例如,我没有根据您的具体表格进行操作,但您会看到影响。假设您要显示按品种分组的页面。然后,用户选择一个品种,他们可以看到该品种的所有条目。
PonyID ProfileGenderID Breeder
1 1 1
2 1 1
3 2 2
4 3 3
5 1 2
6 1 3
7 2 3
Assuming your Gender table is a lookup where ex:
BreedGenderID Description
1 Stallion
2 Mare
3 Geldings
SELECT * FROM个人资料 INNER JOIN prm_breedgender ON profiles.ProfileGenderID = prm_breedgender.BreedGenderID
select
BG.Description,
count(*) as CountPerBreed
from
Profiles P
join prm_BreedGender BG
on p.ProfileGenderID = BG.BreedGenderID
group by
BG.Description
order by
BG.Description
会产生类似的结果(计数只是偶然顺序)
Description CountPerBreed
Geldings 1
Mare 2
Stallion 4
将“order by”子句更改为“按CountsPerBreed Desc排序”(用于降序),您将获得
Description CountPerBreed
Stallion 4
Mare 2
Geldings 1
要扩展,如果您希望每个种鸽分解聚合...最佳做法是将所有非聚集的东西分组(例如MIN(),MAX(),AVG(),COUNT (),SUM()等)
select
BG.Description,
BR.BreaderName,
count(*) as CountPerBreed
from
Profiles P
join prm_BreedGender BG
on p.ProfileGenderID = BG.BreedGenderID
join Breeders BR
on p.Breeder = BR.BreaderID
group by
BG.Description,
BR.BreaderName
order by
BG.Description
会产生类似的结果(计数只是偶然顺序)
Description BreaderName CountPerBreed
Geldings Bill 1
Mare John 1
Mare Sally 1
Stallion George 2
Stallion Tom 1
Stallion Wayne 1
正如您所看到的,您为组提供的粒度越多,每个级别的聚合就越小。
根据您提供的内容,您的加入条件显然是明白的。希望此示例清楚地提供查询过程将执行的操作。你的小组不必与最终订单相同......只是通常看到有人看到结果并不是想要猜测数据是如何组织的。
在您的样本中,您有出生年份的订单。当进行聚合时,你将永远不会有单个小马的特定出生年份,以便按顺序排序......除非......你将YEAR(ProfileYearOfBirth)作为一个列包含在BirthYear中,并包含在你的小组中。 ..例如,1岁时有100匹小马,给定品种的2岁时有37只。
答案 2 :(得分:0)
如果您提供了表结构和大致行数的详细信息,那将会很有帮助。使用'*'作为SELECT也是一种混乱的做法 - 以后会引起你的问题(见下文)。
这是什么版本的MySQL?
显然需要重新组织我的查询以容纳我的主要SELECT子句中的GROUP
不一定从v4(?IIRC)开始,您可以将查询包装在合并选择中(但将限制移到外部选择中:
SELECT ProfileGenderID, COUNT(*)
FROM (
[your query without the LIMIT]
) ilv
GROUP BY ProfileGenderID
LIMIT $limit;
(注意你不能通过ilv.ProfileYearOfBirth ORDER BY,因为它不是按表达式选择的列/组)
prm_breedgender中有多少条记录/列?它只是Stallions,Mares,Geldings ......?你认为这个清单可能会改变吗?你有多种性别的小马吗?我怀疑这个域可以更好地由配置文件表中的枚举表示。
旨在能够列出小马的所有者和饲养员,
使用您建议的代码,您将只返回所有者和饲养员相同的返回实例!您需要使用不同的别名添加contacts表的第二个实例以获取所有这些实例,例如
SELECT *
FROM (
SELECT *
FROM profiles
INNER JOIN prm_breedgender
ON profiles.ProfileGenderID = prm_breedgender.BreedGenderID
LEFT JOIN contacts ownerContact
ON profiles.ProfileOwnerID = ownerContact.ContactID
INNER JOIN prm_breedcolour
ON profiles.ProfileAdultColourID = prm_breedcolour.BreedColourID
) ilv LEFT JOIN contacts breederContact
ON ilv.ProfileBreederID = breederContact.ContactID
ORDER BY ilv.ProfileYearOfBirth ASC $limit