5

私はテーブルスキーマを持っています

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

私は2つのクエリで立ち往生しています:

1)同じ場所に住む写真家のみが写っているような写真。各写真を1回リストします。つまり、写真には写真家である人物が含まれている必要があり、全員が同じ場所に住んでいる必要があります。

2)その場所のすべての写真が、マサチューセッツ州のどの写真にも写っていない写真家によって撮影されたという特性を持つ場所ですか?場所ごとに都市のみを表示し、各場所を1回だけ表示します。

私の試み: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'

誰かがこれらのクエリの作成を手伝ってもらえますか?

4

2 に答える 2

1

クエリは、「プロパティXとYを持つ個々のアイテムを一覧表示し、XとYは異なるテーブルにある」という種類の両方です。

EXISTSこれらのタイプの質問は、通常、およびとの相関サブクエリを使用して解決されNOT EXISTSます。

を使用EXISTSすると、「各アイテムを1回だけ表示する」部分が処理されます。そうしないと、複雑な結合と組み合わせてグループ化を使用する必要があり、これは非常にすぐに混乱する可能性があります。

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

2番目の質問は

[...]その場所のすべての写真が、マサチューセッツ州のどの写真にも写っていない写真家によって撮影されたという特性を持つ場所ですか?場所ごとに都市のみを表示し、各場所を1回だけ表示します。

対応する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>
  )
于 2012-10-08T07:27:02.377 に答える
0

Query1に対する私の試み。同じ都市に住む写真家を写した写真。

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

Query2に対する私の試み。マサチューセッツで撮影された写真に写っている人物の参照を取り、その人物が撮影していない写真をすべてリストします。

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

お役に立てば幸いです。

于 2012-10-07T22:26:12.103 に答える