使用多个别名在同一表和列上进行多个连接

时间:2012-09-10 22:29:57

标签: mysql sql

我有一个名人照片网站。它有一个表,其中包含每张名为photoSearch的照片的所有可搜索数据,并且整个数据集分布在许多表(规范化)上,名为photosphotoPeople和{{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的照片,我只是无法将整个事情联系起来!

1 个答案:

答案 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:)