2012-10-07 13 views
5

Ich habe ein Tabellenschema alsFest mit einer MySQL-Abfrage

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) 
); 

ich zwei Abfragen steckte:

1) Die Fotos, so dass das Foto nur Fotografen zeigt, die in der gleichen Lage leben. Listen Sie jedes Foto einmal auf. Das heißt, Fotos müssen Personen haben, die Fotografen sind, und alle müssen am selben Ort leben.

2) Die Orte, die die Eigenschaft haben, dass jedes Foto in der Position von einem Fotografen genommen wurde, der in keinem Foto in Massachusetts gezeigt wird? Zeigen Sie für jeden Standort nur die Stadt an und zeigen Sie jeden Standort nur einmal an.

Meine Versuche: 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)) 

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' 

Kann mir jemand helfen, diese Abfragen bei der Schaffung von ??

+5

Sie 'JOIN's Forschung sollte – Kermit

+3

@eakron ich bin nicht sicher, es wichtig ist, dass es Hausaufgaben ist. Das OP hat gepostet, was sie versucht haben. – Kermit

+1

@njk es wichtig ist, weil wir keine vollständigen Code-Lösungen für die Hausaufgaben geben sollten –

Antwort

1

Ihre Abfragen sind beide der "listet einzelne Elemente auf, die Eigenschaften X und Y haben, wobei X und Y in verschiedenen Tabellen" Varietät sind.

Diese Art von Fragen werden häufig mit korrelierten Unterabfragen mit EXISTS und NOT EXISTS gelöst.

Verwenden EXISTS kümmert sich um die "zeigen Sie jeden Artikel nur einmal" Teil. Andernfalls müssten Sie Gruppierung in Verbindung mit komplexen Joins verwenden, und dies kann sehr schnell unordentlich werden.

Frage 1 erfordert:

[...] Fotos müssen Personen, die Fotografen sind, und sie alle müssen in dem gleichen Ort leben.

Beachten Sie, dass diese Definition nicht besagt "zeige keine Fotos, wenn sie auch andere Personen enthalten". Wenn Sie das wirklich gemeint haben, liegt es an Ihnen, aus dem unten stehenden SQL Schlüsse zu ziehen und beim nächsten Mal bessere Definitionen zu schreiben. ;)

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 
    ) 
) 

Die zweite Frage lautet

[...] Standorte, die die Eigenschaft haben, dass jedes Foto in der Lage von einem Fotografen gemacht, die nicht in jedem Foto in Massachusetts gezeigt wird? Zeigen Sie für jeden Standort nur die Stadt an und zeigen Sie jeden Standort nur einmal an.

Die nach SQL würde wie folgt aussehen:

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> 
) 
0

Mein Versuch für Query1. Fotos, die Fotografen zeigen, die in der gleichen Stadt leben.

select ph.id, ph.takenAt, ph.takenBy, ph.photographedAt from Photo as ph 
    join Appearance as a on ph.id = a.isShownIn 
    join Photographer as p on a.shows = p.id where p.livesIn in 
     (select p1.id from Photographer as p1, Photographer as p2 
     where p1.id != p2.id and p1.livesIn = p2.livesIn); 

Mein Versuch für Query2. Nehmen Sie Referenzen von Personen, die auf einem Foto in Massachusets gezeigt werden, auf und listen Sie alle Bilder auf, die nicht von diesen Personen aufgenommen wurden.

select * from Photo where takenBy not in 
    (select a.shows from Photo as ph 
     join Location as l on ph.photographedAt = l.id 
     join Appearance as a on a.isShownIn = ph.id 
     where city = 'Massachusets'); 

Hoffe, dass hilft.

+0

nopes es ist nicht richtig :(Ich bin bei den Anfragen von so lange fest .. fast einen Tag! –

+0

danke für Ihre obwohl, –

+0

Entschuldigung, ich habe nicht von der Tabelle Aussehen erkannt. Ich habe die Antwort bearbeitet. In jedem Fall ist es schwierig, ein funktionierendes Ergebnis ohne Daten zu finden, aber ich hoffe, dass dies Ihnen einige Hinweise geben kann, wie Sie bekommen, was Sie wollen. Wie andere aufzeigen, werfen Sie einen Blick auf JOINs. –

Verwandte Themen