我可以在sql中进行多键连接吗?

时间:2016-05-13 13:32:50

标签: sql

需要一些有关此查询的帮助。我正在尝试创建一个选择所有父详细信息的查询,并且我有另一个要附加的表,称为Family。我遇到的问题是Family表包含一个FamilyListID字段,其中包含通过回车分隔的Pupil和Parents的主键。当然可能会有几个ID,因为学生可能有兄弟姐妹,所以这些都存储在这个领域。

有没有办法可以加入多个Pupil.pk_PupilID,Father.pk_PersonID,Mother.pk_PersonID来关联Family.FamilyListID,记住可能没有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 

1 个答案:

答案 0 :(得分:1)

您真正的问题是您的数据结构。您需要将所需数据提取到结构正确的临时表中,然后执行连接或修复数据模型。这就是我使用split函数执行此操作的方法。如果您搜索分割功能,有很多这些可用。选择最符合您需求的产品。我必须用|替换CRLF,因为我的函数只允许使用单个字符分隔符。

如果您搜索周围,可能会找到一个允许您使用更长分隔符的方法。无论如何,这可以让您了解如何使数据可用于您可以加入的数据。此代码是在SQL Server中编写的。我没有提供功能代码,因为不知道你拥有什么数据库后端很难说明什么会有效,这更像是指向你需要做的事情。

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

现在真正的问题是随着你的表变大,这将变得很慢,因为每次运行查询时都必须转换整个表。这就是为什么这个结构是你需要修复的失败者。

如果您无法替换此表,请查看是否可以创建另一个设计合理的表,使用您选择的拆分功能并填充它,然后在原始数位板上使用触发器填充它,以便更新,删除或在原始表中更改记录时插入第二个表。这是一个妥协的解决方案,但至少只有当数据发生变化而不是每次运行查询时,您才需要对记录进行拆分。