2016-05-13 6 views
0

このクエリのヘルプが必要です。私はすべての親の詳細を選択するクエリを作成しようとしているし、私は別のテーブルを持っていると呼ばれるファミリー。私が持っている問題は、Familyテーブルには、瞳孔と親の主キーがキャリッジリターンで区切られたFamilyListIDフィールドが含まれているということです。もちろん、生徒は兄弟を持つかもしれないので、そこにはいくつかのIDがあるかもしれないので、これはすべてこのフィールドに格納されています。sqlでマルチキー結合を実行できますか?

Family.FamilyListIDに関連するmulti Pupil.pk_PupilID、Father.pk_PersonID、Mother.pk_PersonIDに参加する方法はありますか?状況に応じてFather.pk_PersonIDまたはMother.pk_PersonIDが存在しないことに注意してください瞳孔の希望は意味がある - 私は家族と生徒の間に現実的に結合テーブルが必要であることを知っていますが、これは私が現在作業しなければならない構造です。

SELECT 
    Pupil.pk_PupilID, Pupildata.Title, Pupildata.Forename, 
    Pupildata.Surname, Pupildata.PreferredForename, 
    father.pk_PersonID, father.Title, father.Forename, father.Surname, 
    mother.pk_PersonID, mother.Title, mother.Forename, mother.Surname, 
    Pupil.Form, 
    Address.Address1, Address.Address2, Address.TownCity, Address.Postcode, 
    Address.Country, Address.County 
FROM 
    Pupil 
LEFT JOIN 
    PERSON AS Pupildata ON Pupil.pk_PupilID = Pupildata.pk_PersonID 
LEFT JOIN 
    RELATION AS rfather ON Pupil.pk_PupilID = rfather.fk_PersonID 
LEFT JOIN 
    PERSON AS father ON rfather.fk_RelatedPersonID = father.pk_PersonID 
LEFT JOIN 
    RELATION AS rmother ON Pupil.pk_PupilID = rmother.fk_PersonID 
LEFT JOIN 
    PERSON AS mother ON rmother.fk_RelatedPersonID = mother.pk_PersonID 
LEFT JOIN 
    PERSONADDRESS AS pa ON Pupil.pk_PupilID = pa.fk_PersonID 
LEFT JOIN 
    ADDRESS ON pa.fk_AddressID = Address.pk_AddressID 
WHERE 
    Pupil.pk_PupilID IN ('" & pks & "') 
    AND rfather.Relationship IN ('Father', 'Stepfather') 
    OR rmother.Relationship IN ('Mother', 'Stepmother') 
    AND Address.PrimaryAddress = 1 
ORDER BY 
    Pupildata.Forename ASC 
+0

これらをすべてクロスさせ、where節に制約を移します。ほとんどのデータベースは正しいことを行い、実際にはクロス結合を実行しません。 –

+0

これは実際にはデータベース設計上の問題のように聞こえると言わなければなりません。キャリッジリターンで区切られた単一のテキストフィールドに複数のキーがあると、データベースの目的を完全に破ります。個人をすべての家族に関連付ける関係テーブルを持っている方が良いか、それぞれが関連しているファミリーテーブルを持っているほうがよいでしょう。 したがって、ファミリーテーブルの列に複数のPerson IDを持つのではなく、PersonテーブルにFamily IDを設定します。 –

+0

その構造はすべての時間のために確かな敗者なので、今私はそれを修正するだろう。フィールド内にキャリッジリターンを持つ行にデータを格納し、他のテーブルと比較するために部品を引き出したいという理由はありません。 – HLGEM

答えて

1

実際の問題はデータ構造です。必要なデータを適切に構造化されたテンポラリテーブルに引き出し、データモデルに参加または修正する必要があります。これは私が分割関数を使ってこれを行った方法です。分割機能を探し回っている場合は、これらの機能が十分に用意されています。ニーズに合ったものを選んでください。私の関数は単一の文字区切り文字しか許さないので、CRLFを|に置き換えなければなりませんでした。

周囲を検索すると、長い区切り文字を使用できるようになる場合があります。いずれにせよ、これはあなたが参加できるものの中でデータを入手する方法のアイデアを提供します。このコードはSQLサーバーで作成されました。私は機能コードを提供していません。なぜなら、何のデータベースバックエンドを知っていなくても、正確に何がうまくいくと言うのが難しいからです。これは、あなたが何をする必要があるのか​​を指示するものです。あなたのテーブルが大きくなるにつれて

Create table #test (Familyid int, Detail varchar(100)) 
insert into #test(Familyid, Detail) 
values (1, '1 '+char(13)+char(10)+ '2 ' +char(13)+char(10)+ '3') 
,(2, '4 '+char(13)+char(10)+ '5 ' +char(13)+char(10)+ '6') 
,(3, '7 '+char(13)+char(10)+ '8 ') 
select * from #test 

update #test 
set detail = replace (detail, char(13)+char(10), '|') 


select t.familyid, cast(splitdata as Int) as ID 
into #test2 
from #test t 
cross apply dbo.fn_Split_String (detail, '|') 

select * from #test2 

今、本当の問題はしかしある、これはあなたが全体のテーブルにクエリを実行するたびに変換する必要がありますように遅い汚れになるだろう。これが、この構造が生きていないことを修正する必要がある敗者である理由です。

このテーブルを置き換えることができない場合は、適切に設計された別のテーブルを作成し、選択した分割機能を使用してデータを入力し、元のタブレットの更新、削除元のテーブルでレコードが変更されると、2番目のテーブルに挿入されます。これは妥協策ですが、少なくともクエリを実行するたびにデータを変更するのではなく、レコードを分割するだけで済みます。

関連する問題