我有一个表模式
create table Location(
id int primary key,
city varchar(255),
state varchar(100),
country varchar(255)
);
create table Person(
id int primary key,
name varchar(100)
);
create table Photographer(
id int primary key references Person(id) on update cascade on delete cascade,
livesIn int not null references Location(id) on update cascade on delete no action
);
create table Specialty(
photographer int references Photographer(id) on update cascade on delete cascade,
type enum('portrait','landscape','sport'),
primary key(photographer, type)
);
create table Photo(
id int primary key,
takenAt timestamp not null,
takenBy int references Photographer(id) on update cascade on delete no action,
photographedAt int references Location(id) on update cascade on delete no action
);
create table Appearance(
shows int references Person(id) on update cascade on delete cascade,
isShownIn int references Photo(id) on update cascade on delete cascade,
primary key(shows, isShownIn)
);
Run Code Online (Sandbox Code Playgroud)
我被困在两个问题:
1)照片使照片仅显示居住在同一位置的摄影师.列出每张照片一次.也就是说,照片必须有摄影师,他们都需要住在同一个地方.
2)拥有该地点的每张照片的地点都是由摄影师在马萨诸塞州的任何照片中拍摄的?对于每个位置仅显示城市,并仅显示每个位置一次.
我的尝试:1)
SELECT ph.id, ph.takenAt, ph.takenBy, ph.photographedAt FROM
(SELECT * FROM Photo p, Appearance ap WHERE p.id = ap.isShownIn
HAVING ap.shows IN (SELECT person.id FROM Person,Photographer WHERE person.id
photographer.id)) ph
WHERE ph.photographedAt = (SELECT location.id FROM location WHERE location.id =
(SELECT livesIn FROM Photographer WHERE id = ph.takenBy))
Run Code Online (Sandbox Code Playgroud)
2)
select distinct city from location where location.id in (
select photographedAt from photo, (select * from appearance where appearance.shows in
(select photographer.id from photographer)) ph
where photo.id = ph.isShownIn )
and location.state <> 'Massachusetts'
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助创建这些查询?
您的查询都是“列出具有属性 X 和 Y 的单个项目,其中 X 和 Y 位于不同的表中”的类型。
EXISTS这些类型的问题通常使用和的相关子查询来解决NOT EXISTS。
使用EXISTS处理“每个项目仅显示一次”部分。否则,您将需要将分组与复杂的连接结合使用,这很快就会变得混乱。
问题1要求:
[...] 照片必须有摄影师,而且他们都需要住在同一个地方。
请注意,此定义并没有说“如果照片中也包含其他人,则不要显示照片”。如果这就是您真正的意思,那么您就需要从下面的 SQL 中得出结论,并在下次编写更好的定义。;)
SELECT
*
FROM
Photo p
WHERE
EXISTS (
-- ...that has at least one appearance of a photographer
SELECT
1
FROM
Appearance a
INNER JOIN Photographer r ON r.id = a.shows
INNER JOIN Location l ON l.id = r.livesIn
WHERE
a.isShownIn = p.id
-- AND l.id = <optional location filter would go here>
AND NOT EXISTS (
-- ...that does not have an appearance of a photographer from
-- some place else
SELECT
1
FROM
Appearance a1
INNER JOIN Photographer r1 ON r1.id = a1.shows
INNER JOIN Location l1 ON l1.id = r1.livesIn
WHERE
a1.isShownIn = p.Id
AND l1.id <> l.id
)
)
Run Code Online (Sandbox Code Playgroud)
第二个问题是这样写的
[...] 某个地点的属性是,该地点的每张照片均由未出现在马萨诸塞州任何照片中的摄影师拍摄?对于每个位置仅显示城市,并且每个位置仅显示一次。
相应的 SQL 如下所示:
SELECT
city
FROM
Location l
WHERE
NOT EXISTS (
-- ...a photo at this location taken by a photographer who makes
-- an apperance on another photo which which was taken in Massachusetts
SELECT
1
FROM
Photo p
INNER JOIN Photographer r ON r.id = p.takenBy
INNER JOIN Appearance a ON a.shows = r.id
INNER JOIN Photo p1 ON p1.id = a.isShownIn
WHERE
p.photographedAt = l.Id
AND p1.photographedAt = <the location id of Massachusetts>
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |