每行SQL XML多个元素

时间:2016-10-24 09:24:18

标签: sql-server xml tsql grouping for-xml

我的设置如下:

TableA - ID, PolicyReference, PolicyNumber

TableB - ID, Drivers, DOB, Sex

将一条记录插入到TableA中,该记录具有唯一ID,策略参考和该策略的策略编号。

每个政策'然后可以在该策略上有多个驱动程序,在TableB中ID是UNIQUE并且是TableA和TableB之间的JOIN,现在我已经完全编写了我的SELECT XML查询,直到这一点,因为当我不包含TableB时它返回每条记录有1行,但是当我包含TableB时,如果有超过1个驱动程序,则会将其混乱。

以下是我当前从1行返回的示例XML:

<PCNewBusiness>
<PolicyNumber>999999999</PolicyNumber>
<StartDate>2016-10-17T00:00:002017-10-17T00:00:00</StartDate>
<Premium>
  <NetAmount>100.00</NetAmount>
  <IPT>10.00</IPT>
</Premium>
<Fee>
  <NetAmount>50.00</NetAmount>
  <IPT>0</IPT>
</Fee>
<Policyholder>
  <PolicyholderType>
    <PrivateIndividual>
      <Name>
        <Title>Mr</Title>
        <FirstNames>Bob</FirstNames>
        <LastName>Test</LastName>
      </Name>
      <DateOfBirth>1985-12-03T00:00:00</DateOfBirth>
      <MaritalStatus>Single</MaritalStatus>
      <Sex>Male</Sex>
    </PrivateIndividual>
  </PolicyholderType>
  <Contact>Mr Bob Test</Contact>
  <Address>
    <Address1>This</Address1>
    <Address2>Test</Address2>
    <Address3>Address</Address3>
    <Address4>Is Fake</Address4>
    <Postcode>BB2 1AB</Postcode>
  </Address>
  <Phone>07777777777</Phone>
  <Email>mytestaccount@gmail.com</Email>
</Policyholder>
<Cover>
  <CoverType>Comprehensive</CoverType>
  <PolicyExcess>600</PolicyExcess>
  <NoClaimsBonusYears>9</NoClaimsBonusYears>
  <NCBOtherVehicle>0</NCBOtherVehicle>
  <Use>Class1</Use>
</Cover>

现在,当我加入TableB时,它返回上面的信息,但是两次,我知道这是因为识别出的ID上的连接在TableB中返回了2行,因为有2个驱动程序。

加入TableB时,这将是我的 EXPECTED 输出。

<Cover>
    <CoverType>Comprehensive</CoverType>
    <PolicyExcess>600</PolicyExcess>
    <NoClaimsBonusYears>9</NoClaimsBonusYears>
    <NCBOtherVehicle>0</NCBOtherVehicle>
    <Use>Class1</Use>
</Cover>
<Drivers>
    <Driver>
        <RelationshipToPolicyholder>Policyholder</RelationshipToPolicyholder>
        <Name>
            <Title>Mr</Title>
            <FirstNames>Bob</FirstNames>
            <LastName>Test</LastName>
        </Name>
        <DateOfBirth>1972-07-14</DateOfBirth>
        <LicenceType>FullUK</LicenceType>
        <PeriodLicenceHeld>MoreThanFiveYears</PeriodLicenceHeld>
        <HomeAddress>
            <Address1>Another Test</Address1>
            <Address2>Address</Address2>
            <Address3>Thats Fake</Address3>
            <Postcode>AA1 1ZZ</Postcode>
        </HomeAddress>
        <PeriodResident>MoreThanFiveYears</PeriodResident>
        <VehicleUseFrequency>Daily</VehicleUseFrequency>
        <HasUseOfOtherVehicle>false</HasUseOfOtherVehicle>
        <MainOccupation>Software Engineer</MainOccupation>
        <HasCriminalConvictions>1</HasCriminalConvictions>
    </Driver>
    <Driver>
        <RelationshipToPolicyholder>Spouse</RelationshipToPolicyholder>
        <Name>
            <Title>Mrs</Title>
            <FirstNames>Jill</FirstNames>
            <LastName>Test</LastName>
        </Name>
        <DateOfBirth>1972-07-14</DateOfBirth>
        <LicenceType>FullUK</LicenceType>
        <PeriodLicenceHeld>MoreThanFiveYears</PeriodLicenceHeld>
        <HomeAddress>
            <Address1>Another</Address1>
            <Address2>Test</Address2>
            <Address3>Address</Address3>
            <Postcode>BB1 1BZ</Postcode>
        </HomeAddress>
        <PeriodResident>MoreThanFiveYears</PeriodResident>
        <VehicleUseFrequency>Daily</VehicleUseFrequency>
        <HasUseOfOtherVehicle>false</HasUseOfOtherVehicle>
        <MainOccupation>Housewife</MainOccupation>
        <HasCriminalConvictions>1</HasCriminalConvictions>
    </Driver>
</Drivers>

基本上我想返回1行数据但是当我加入TableB时,我需要使用TableB中2行的数据来填充&#39; Drivers&#39;之间的所有内容。元件。

需要更多信息请远离。

更新

我目前的SELECT查询请求。

SELECT  ROW_NUMBER() OVER ( ORDER BY ( SELECT   NULL
                                 ) ) AS "PolicyRecordNumber",
    sub.Polno AS "PCNewBusiness/PolicyNumber",
    sub.[Inception Date] AS "PCNewBusiness/StartDate",
    sub.[Renewal Date] AS "PCNewBusiness/StartDate",
    sub.PremXIPT AS "PCNewBusiness/Premium/NetAmount",
    sub.PremIPT AS "PCNewBusiness/Premium/IPT",
    sub.FeeXIPT AS "PCNewBusiness/Fee/NetAmount",
    sub.FeeIPT AS "PCNewBusiness/Fee/IPT",
    ph.Title AS "PCNewBusiness/Policyholder/PolicyholderType/PrivateIndividual/Name/Title",
    ph.Firstname AS "PCNewBusiness/Policyholder/PolicyholderType/PrivateIndividual/Name/FirstNames",
    ph.Surname AS "PCNewBusiness/Policyholder/PolicyholderType/PrivateIndividual/Name/LastName",
    ph.DateOfBirth AS "PCNewBusiness/Policyholder/PolicyholderType/PrivateIndividual/DateOfBirth",
    ph.MaritalStatus AS "PCNewBusiness/Policyholder/PolicyholderType/PrivateIndividual/MaritalStatus",
    ph.Sex AS "PCNewBusiness/Policyholder/PolicyholderType/PrivateIndividual/Sex" ,
    ph.Contact AS "PCNewBusiness/Policyholder/Contact",
    ph.Addr1 AS "PCNewBusiness/Policyholder/Address/Address1",
    ph.Addr2 AS "PCNewBusiness/Policyholder/Address/Address2",
    ph.Addr3 AS "PCNewBusiness/Policyholder/Address/Address3",
    ph.Addr4 AS "PCNewBusiness/Policyholder/Address/Address4",
    ph.Pcode AS "PCNewBusiness/Policyholder/Address/Postcode",
    ISNULL(ph.Tel,ph.Tel2) AS "PCNewBusiness/Policyholder/Phone",
    ph.Email AS "PCNewBusiness/Policyholder/Email",
    cov.Cover AS "PCNewBusiness/Cover/CoverType",
    cov.Excess AS "PCNewBusiness/Cover/PolicyExcess",
    cov.NCBYears AS "PCNewBusiness/Cover/NoClaimsBonusYears",
    cov.NCBOtherVeh AS "PCNewBusiness/Cover/NCBOtherVehicle",
    cov.ClassOfUse AS "PCNewBusiness/Cover/Use",
    --dri.RelationshipToPH AS "PCNewBusiness/Drivers/Driver/RelationshipToPolicyHolder",
    --dri.Drivertitle AS "PCNewBusiness/Drivers/Driver/Title" ,
    --dri.FirstName AS "PCNewBusiness/Drivers/Driver/FirstNames" ,
    --dri.Surname AS "PCNewBusiness/Drivers/Driver/LastName"
    veh.Make AS "PCNewBusiness/Vehicles/Vehicle/Make",
    veh.Model AS "PCNewBusiness/Vehicles/Vehicle/Model",
    veh.Reg AS "PCNewBusiness/Vehicles/Vehicle/RegistrationNumber",
    veh.Body AS "PCNewBusiness/Vehicles/Vehicle/BodyType",
    veh.Parking AS "PCNewBusiness/Vehicles/Vehicle/LocationWhenNotInUse",
    '' AS "PCNewBusiness/Vehicles/Vehicle/AnnualMileage",
    veh.YearMade AS "PCNewBusiness/Vehicles/Vehicle/YearOfManufacture",
    veh.Engine_size AS "PCNewBusiness/Vehicles/Vehicle/EngineSizeCc",
    veh.Purchasedate AS "PCNewBusiness/Vehicles/Vehicle/PurchaseDate",
    veh.Value AS "PCNewBusiness/Vehicles/Vehicle/PurchasePrice",
    veh.Value1 AS "PCNewBusiness/Vehicles/Vehicle/EstimatedValue",
    veh.Seats AS "PCNewBusiness/Vehicles/Vehicle/NumberOfSeats",
    veh.RightHandDrive AS "PCNewBusiness/Vehicles/Vehicle/RightHandDrive",
    veh.Fuel AS "PCNewBusiness/Vehicles/Vehicle/FuelType"
FROM    dbo.Submissions sub
    LEFT OUTER JOIN dbo.PolicyHolder ph ON ph.ID = sub.ID
    LEFT OUTER JOIN dbo.Cover cov ON cov.ID = sub.ID
    --LEFT OUTER JOIN dbo.Drivers dri ON dri.ID = sub.ID
    LEFT OUTER JOIN dbo.Vehicle veh ON veh.ID = sub.ID
    --LEFT OUTER JOIN dbo.Convictions con ON con.ID = sub.ID
    --LEFT OUTER JOIN dbo.Claims cla ON cla.ID = sub.ID
    --LEFT OUTER JOIN dbo.Medical med ON med.ID = sub.ID
WHERE sub.[Transaction] = 'New Business' AND sub.[Ledger Date] >= dbo.Today()-7
FOR     XML PATH('Policy')

更新2

好的,我已经在我的&#39;驱动程序&#39;的子查询中输入了进度。选择如下:

   cov.Cover AS "PCNewBusiness/Cover/CoverType" ,
    cov.Excess AS "PCNewBusiness/Cover/PolicyExcess" ,
    cov.NCBYears AS "PCNewBusiness/Cover/NoClaimsBonusYears" ,
    cov.NCBOtherVeh AS "PCNewBusiness/Cover/NCBOtherVehicle" ,
    cov.ClassOfUse AS "PCNewBusiness/Cover/Use" ,
    ( SELECT    dri1.ID ,
                RelationshipToPH ,
                dri1.FirstName ,
                dri1.Surname
      FROM      dbo.Drivers dri1
                INNER JOIN dbo.Submissions sub1 ON sub1.ID = dri1.ID
    FOR
      XML PATH('Driver') ,
          TYPE
    ) AS "PCNewBusiness/Drivers" 

这会将我需要它们的地方的驱动程序返回给HOWEVER,子查询正在拉动“驱动程序”中的每一行。表,而不是该UNIQUE ID的每个驱动程序的相关行。

见下文:

    <Cover>
  <CoverType>Comprehensive</CoverType>
  <PolicyExcess>600</PolicyExcess>
  <NoClaimsBonusYears>4</NoClaimsBonusYears>
  <NCBOtherVehicle>0</NCBOtherVehicle>
  <Use>Class1</Use>
</Cover>
<Drivers>
  <Driver>
    <ID>1</ID>
    <RelationshipToPH>Policyholder</RelationshipToPH>
    <FirstName>John</FirstName>
    <Surname>Doe</Surname>
  </Driver>
  <Driver>
    <ID>2</ID>
    <RelationshipToPH>Commonlaw Spouse</RelationshipToPH>
    <FirstName>Bob</FirstName>
    <Surname>Test</Surname>
  </Driver>
  <Driver>
    <ID>2</ID>
    <RelationshipToPH>Policyholder</RelationshipToPH>
    <FirstName>Jill</FirstName>
    <Surname>Test</Surname>
  </Driver>
  <Driver>
    <ID>3</ID>
    <RelationshipToPH>Policyholder</RelationshipToPH>
    <FirstName>Jane</FirstName>
    <Surname>Gowe</Surname>
  </Driver>
  <Driver>
    <ID>4</ID>
    <RelationshipToPH>Policyholder</RelationshipToPH>
    <FirstName>Dave</FirstName>
    <Surname>Grace</Surname>
  </Driver>

我的第一行应该只返回2个带ID的驱动程序&#34; 2&#34;例如。

1 个答案:

答案 0 :(得分:2)

你自己的更新2正是我想建议你的事情......

现在我认为其余的很容易:

将您的子选择的off更改为简单的JOIN

WHERE