我有一个名人照片网站。它有一个表,其中包含每张名为photoSearch
的照片的所有可搜索数据,并且整个数据集分布在许多表(规范化)上,名为photos
,photoPeople
和{{1} }。
表people
包含photoID和peopleID,photoPeople
表包含peopleID和人名。 people
表包含标题,标题,高度,宽度,文件大小,销售代码等。
这是我目前的脚本,可以产生良好的效果。
photos
问题是,我现在想要搜索一个或多个名人姓名以改变结果,而不是仅选择要在结果中显示的名人姓名。
我很确定在同一列上添加两个或更多where子句是不可能的(pe.people ='angelina jolie'和pe.people ='brad pitt'),所以我很确定它需要使用JOINS来完成。
这让我很困惑。所以我在这里问了一个问题,以找出如何实现这个目标并且有人建议:“加入'photoPeople'和'人员'表 n 次,其中 n 是 你要搜索的人数。“
我尝试了许多不同的方法来实现这一目标,但到目前为止都失败了。我知道他所说的涉及删除两行星号(上面的代码)之间的连接,并将 n 连接数替换为people表,但我只是无法理解。
我尝试了这个,但phpMyAdmin现在已经考虑了最后10分钟!:
SELECT
p.photoID,
p.setID,
p.headline,
p.caption,
GROUP_CONCAT(pe.people ORDER BY pe.people ASC SEPARATOR ';') AS people
FROM
photos p
INNER JOIN
(
SELECT photoID
FROM photoSearch
WHERE MATCH (allKeywords, shortCaption)
AGAINST ('+red +dress +claridges +hotel' IN BOOLEAN MODE)
LIMIT 50
) pids ON p.photoID = pids.photoID
***********
LEFT JOIN
photoPeople pp ON p.photoID = pp.photoID
LEFT JOIN
people pe ON pp.peopleID = pe.peopleID
***********
GROUP BY p.photoID
除了上面尝试FOREVER之外,我还很难看到如何改变GROUP_CONCAT函数以从多个连接/别名(p1,p2,p3等)获得结果!
拜托,我希望得到一些正确的建议。
TEST SCENARIO
如果我按原样运行查询,我会看到:
********
JOIN ( photoPeople AS pp1 JOIN people AS p1 ON pp1.peopleID = p1.peopleID)
ON p1.people = 'Brad Pitt'
JOIN ( photoPeople AS pp2 JOIN people AS p2 ON pp2.peopleID = p2.peopleID)
ON p2.people = 'Angelina Jolie'
********
我希望我的新查询能够搜索姓名,所以如果我搜索Angeline Jolie和Brad Pitt,我只会看到这个:
Photo: 120030
Set: 8803
Headline: Brad and Angelina arrive at film premiere.
People: Brad Pitt; Angelina Jolie
Photo: 120031
Set: 8803
Headline: Brad and Angelina arrive at film premiere.
People: Angelina Jolie
Photo: 120032
Set: 8803
Headline: Brad and Angelina arrive at film premiere.
People: Brad Pitt
NEW ATTEMPT:
没有错误但是返回0结果,其中'Brad Pitt'和'Angelina Jolie'应该在'France'中有1000个结果。
Photo: 120030
Set: 8803
Headline: Brad and Angelina arrive at film premiere.
People: Brad Pitt; Angelina Jolie
如果我删除INNER JOIN部分并运行它,它会返回Brad和Angelina的所有照片,无论它们是否在一起,这是不正确的 - 我只需要它们在一起。如果我也删除了SELECT
p.photoID,
p.setID,
p.headline,
p.caption,
GROUP_CONCAT(pe.people ORDER BY pe.people ASC SEPARATOR ';') AS people
FROM
photos p
INNER JOIN
(
SELECT photoID
FROM photoSearch
WHERE MATCH (allKeywords, shortCaption)
AGAINST ('+France' IN BOOLEAN MODE)
LIMIT 50
) pids ON p.photoID = pids.photoID
LEFT JOIN
photoPeople pp ON p.photoID = pp.photoID
JOIN
people pe ON pp.peopleID = pe.peopleID
AND (pe.people = 'Angelina Jolie' OR pe.people = 'Brad Pitt')
GROUP BY p.photoID
,它会正确地返回Angelina的照片,我只是无法将整个事情联系起来!
答案 0 :(得分:1)
是否有没有photoPeople的照片?还是没有人的照片人?如果不是,请使用常规连接而不是左连接。然后,您可以在该查询中添加额外的where子句
where (people = "Brad Pitt" or people = "Angelina Jolie")
如果您需要保留左连接,可以向ON添加更多条件
... ON pp.peopleID = pe.peopleID and (people = "Brad Pitt" or people = "Angelina Jolie")
更新
我的大脑正在看自我加入的版本,而不是尼古拉的联盟:
select pp1.photoId
from photoPeople pp1, people p1, photoPeople pp2, people p2
where pp1.peopleID = p1.peopleID
and p1.people = "angelina"
and pp2.peopleID = p2.peopleID
and pp1.photoId = pp2.photoId
and p2.people = "brad"
但是它让我想起了我建立的系统,你想要根据匹配数量排名,这对于UNIONS更容易。
SELECT photoID, count(*) as rank
from (
SELECT pp.PhotoID
FROM photoPeople AS pp
JOIN people AS p ON pp.peopleID = p.peopleID
WHERE p.people = 'Brad Pitt'
UNION
SELECT pp.PhotoID
FROM photoPeople AS pp
JOIN people AS p ON pp.peopleID = p.peopleID
WHERE p.people = 'Angelina Jolie'
) foo
group by photoID
order by rank desc
我会选择Nikola:)