2016-05-12 6 views
0

ここは私の質問です。私はポストグレムにいると私は次のを持っているconceptual schemaデカルト積の取得

私の目的は、ゲームをプレイしているゲームのコード、名前のチームと名前の選手を表示することです。私だけでゲームのコードと名前のチームを示すために持っている:私は名前のプレイヤーを取得すぎ

select g.code,t.name,p.surname 
from pldata.team t,pldata.player p,pldata.player p2,pldata.game g,pldata.team t2 
where t.code=p.belongs 
and t2.code=p2.belongs 
and t.code=g.home_team 
and t2.code=g.away_team 
order by code 

のためにこれを行うにしようと試みてきましたしかし、それはデカルト積とIドンを作る

select g.code,home_team,t1.name,away_team,t2.name 
from pldata.game g,pldata.team t1,pldata.team t2 
where t1.code = g.home_team 
and t2.code = g.away_team 
order by 1 

を理由は分かりません。どんな種類の助けもいいですから、ありがとう。

+6

現代的で明示的なJOIN構文に切り替えると、人生がより簡単になります! – jarlh

+0

選択リストを 'g.code、t.name、p.surname、t2を選択するように変更します。AS name2、p2.surname AS surname2'という名前で、あなたはライトを見るでしょう! – joop

+0

私は試み、私はデカルト製品を見続けた。 –

答えて

0

私は仕事中です。あなたがリンクしている画像をチェックすることはできません。あなたは、このような質問をするときに、常にすべてのテーブルのデータサンプルを投稿する方が良いです。

データがないため、推測しかできません。

あなたの最初の間違いは、あなたが JOIN構文を代わりに明示的な JOIN構文を暗黙のを使用することです。これにより、クエリを読みにくくし、デバッグして理解しやすくなります。

これは、明示的な構文に書き換えられたクエリで、あなたは常には、このようなあなたのSQLを構築する必要があります。

SELECT g.code,g.home_team, t1.name, p1.surname, g.away_team, t2.name, p2.surname 
FROM pldata.game g 
INNER JOIN pldata.team t1 ON t1.code=g.home_team 
INNER JOIN pldata.player p1 ON t1.code=p1.belongs 
INNER JOIN pldata.team t2 ON t2.code=g.away_team 
INNER JOIN pldata.player p2 ON t2.code=p2.belongs 
ORDER BY g.code 

とNO CROSS JOINは、このクエリではありませんので、それはデカルト積を返してはいけません。

質問がありますので、はチームのマルチプレイヤーですか?

「はい」の場合、2つのチームの各プレイヤーに1つの行が存在するため、1つのゲームで複数の行が返されます。これはデカルト製品と思われるかもしれません。

明示的な結合構文を使用すると、問合せをデバッグして問題が存在する場合はどこにあるかを理解することが非常に簡単です。プレーヤーテーブルの2つの結合を削除して、もう一度やり直してください。

マルチプレイヤーでゲームごとに1つの行だけが必要な場合でも、結果にすべてのプレーヤーが必要な場合は、GROUP_CONCATを実行する必要があります。この式は後発ではサポートされていませんが、同じことを達成するstring_agg(the_column, ',')を使用することができます。しかし、あなたは唯一のチームの選手のconcatanationを行うことができます。

SELECT g.code, g.home_team, string_agg(p1.surname,',') AS Team1Players 
    FROM pldata.game g 
    INNER JOIN pldata.team t1 ON t1.code=g.home_team 
    INNER JOIN pldata.player p1 ON t1.code=p1.belongs 
    GROUP BY g.code, g.home_team 

1行の両方のチームを持っている解決策は2間jointureを作ることである各チームのGROUP BYクエリを、agreggated:

SELECT Team1.code,Team1.home_team, Team1.Team1Players, Team2.away_team, Team2.Team2Players 
FROM  
( 
    SELECT g.code, g.home_team, string_agg(p1.surname,',') AS Team1Players 
    FROM pldata.game g 
    INNER JOIN pldata.team t1 ON t1.code=g.home_team 
    INNER JOIN pldata.player p1 ON t1.code=p1.belongs 
    GROUP BY g.code, g.home_team 
) Team1 
INNER JOIN 
(
    SELECT g.code, g.away_team, string_agg(p2.surname,',') AS Team2Players 
    FROM pldata.game g 
    INNER JOIN pldata.team t2 ON t2.code=g.away_team 
    INNER JOIN pldata.player p2 ON t2.code=p2.belongs 
    GROUP BY g.code, g.away_team 
) Team2 
ON Team1.Code = Team2.code 
ORDER BY Team1.code 

これはすべてあなたの質問に答えるかどうかわかりませんが、文法上の間違いはしませんでしたが、そのアイデアはありますし、少なくともさらに進んでいくためのヒントはあります。

私の質問がうまくいかない場合や、さらに援助が必要な場合は、私たちが遊び場を持つようにDLLとデータを追加するための質問を絶対に編集する必要があります。

+0

あなたのアドバイスのおかげでトーマス。それはとても有益でした。これはstackoverflowの私の2番目の投稿です、私はそれを行う方法は使用されていません。ジョイントについて私の先生はそれが道ではないと思うので、彼らは私たちにとてもうまく教えませんでした。私はあなたがSQLプログラマとして働いていると思うので、これについてどう思いますか?彼は間違っていますか? –

+0

教師が明示的な結合の代わりに暗黙の結合を使用する必要があることを教えていることを意味するならば、彼は実際に教えを止めるべきです。ちょうどこれについてのグーグルを作ると、彼はどれくらい悪いかの考えを与えるでしょう;-) –

関連する問題