T-SQL连接两个表,其中连接条件取决于两个表中的值

时间:2017-09-22 14:13:55

标签: sql-server tsql

我有一个查询,它结合了两个表的数据。

政策表

PolicyID    PolicyNumber    PolicyStartDate
48  FCO100009   2015-06-01 00:00:00.000
49  FCO100009   2016-06-01 00:00:00.000

索赔表

ClaimID ClaimReference  PolicyNumber    IncidentDatetime    NotificationDatetime    Version
30  287 FCO100009   2015-11-06 00:00:00.000 2015-11-27 00:00:00.000 4. Claim - Incident Date
223 259 FCO100009   2015-11-03 00:00:00.000 2015-11-20 00:00:00.000 4. Claim - Incident Date
1367    988 FCO100009   2016-04-15 00:00:00.000 2016-04-21 00:00:00.000 4. Claim - Incident Date
1561    1859    FCO100009   2016-09-14 00:00:00.000 2016-09-19 00:00:00.000 4. Claim - Incident Date
1741    443275  FCO100009   2016-05-11 00:00:00.000 2016-05-12 00:00:00.000 4. Claim - Incident Date
1742    991 FCO100009   2016-04-20 00:00:00.000 2016-04-21 00:00:00.000 4. Claim - Incident Date
2038    287 FCO100009   2015-11-06 00:00:00.000 2015-11-27 00:00:00.000 5. Claim - Notification Date
3744    259 FCO100009   2015-11-03 00:00:00.000 2015-11-20 00:00:00.000 5. Claim - Notification Date
3745    991 FCO100009   2016-04-20 00:00:00.000 2016-04-21 00:00:00.000 5. Claim - Notification Date
4502    1859    FCO100009   2016-09-14 00:00:00.000 2016-09-19 00:00:00.000 5. Claim - Notification Date
4639    988 FCO100009   2016-04-15 00:00:00.000 2016-04-21 00:00:00.000 5. Claim - Notification Date
6600    443275  FCO100009   2016-05-11 00:00:00.000 2016-05-12 00:00:00.000 5. Claim - Notification Date

对于具有不同政策开始日期的政策,有2条记录,每条索赔记录有2个版本,其中“版本”字段为“声明事件日期”或“声明通知日期”。

我试图完成的是加入PolicyNumber上的两个表,然后将结果中的PolicyStartDate值设置为Policy.PolicyStartDate中的最大值,其中当Version = NotificationDate或PolicyStartDate较少时,PolicyStartDate小于NotificationDate比Version = IncidentDate的事件日期。

请注意,这是使用财务非日历年,在这种情况下,帐户年份从4月到3月。

这是我当前的查询,它没有产生正确的答案:

SELECT  cds.ClaimID,
        cds.ClaimReference,
        p.policyID,
        p.PolicyStartDate,
        cds.IncidentDatetime,
        cds.NotificationDatetime, 
        cds.[Version]
FROM    dbo.ClaimDataStaging cds
        INNER JOIN dbo.[Policy] p
            ON p.PolicyNumber = cds.PolicyNumber
                AND p.PolicyStartDate < CASE WHEN cds.[Version] = '4. Claim - Incident Date' THEN cds.IncidentDatetime
                                        WHEN cds.[Version] = '5. Claim - Notification Date' THEN cds.NotificationDatetime END
WHERE   cds.PolicyNumber = 'FCO100009'
ORDER BY cds.[Version], cds.ClaimReference;         
GO

非常感谢任何帮助或建议。

3 个答案:

答案 0 :(得分:0)

我认为您正在寻找类似下面的查询。它会根据您对日期的过滤器为您提供最大保单号。

SELECT  cds.ClaimID,
        cds.ClaimReference,
        p.policyID,
        p.PolicyStartDate,
        cds.IncidentDatetime,
        cds.NotificationDatetime, 
        cds.[Version]
FROM    dbo.ClaimDataStaging cds
    CROSS APPLY (
            SELECT PolicyStartDate = MAX(fp.PolicyStartDate)
            FROM dbo.[Policy] fp
            WHERE fp.PolicyNumber = cds.PolicyNumber
            AND ((fp.PolicyStartDate < cds.IncidentDatetime AND cds.[Version] = '4. Claim - Incident Date')
                OR (fp.PolicyStartDate < cds.NotificationDatetime AND cds.[Version] = '5. Claim - Notification Date')) sp
    INNER JOIN dbo.[Policy] p ON p.PolicyNumber = cds.PolicyNumber AND p.PolicyStartDate = sp.PolicyStartDate
WHERE   cds.PolicyNumber = 'FCO100009'
ORDER BY cds.[Version], cds.ClaimReference;
GO

答案 1 :(得分:0)

据我了解您的问题和您的问题(由日期条件引起的重复&lt;日期也捕获以前的政策),您也可以尝试此查询。
它使用LEAD()函数计算一种Enddate(我使用IS NULL来捕获最后一个策略,但你可以根据需要改变它)。

我在内部查询中移动了CASE,以避免在WHERE子句中重复它。

SELECT  cds.ClaimID,
        cds.ClaimReference,
        p.policyID,
        p.PolicyStartDate,
        cds.IncidentDatetime,
        cds.NotificationDatetime, 
        cds.[Version]
FROM    (SELECT ClaimID, ClaimReference, IncidentDatetime,NotificationDatetime,[Version], PolicyNumber
        , CASE WHEN [Version] = '4. Claim - Incident Date' THEN IncidentDatetime
               WHEN [Version] = '5. Claim - Notification Date' THEN NotificationDatetime END AS CheckDate
         FROM dbo.ClaimDataStaging) cds
INNER JOIN (SELECT policyID, PolicyNumber, PolicyStartDate
            , LEAD(PolicyStartDate) OVER (PARTITION BY PolicyNumber ORDER BY PolicyStartDate) AS PolicyEndDate FROM dbo.Policy ) p
            ON p.PolicyNumber = cds.PolicyNumber
            AND p.PolicyStartDate <  CheckDate 
            AND (p.PolicyEndDate IS NULL OR p.PolicyEndDate>=CheckDate)
WHERE   cds.PolicyNumber = 'FCO100009'
ORDER BY cds.[Version], cds.ClaimReference;

输出:

+---------+----------------+----------+-------------------------+-------------------------+-------------------------+------------------------------+
| ClaimID | ClaimReference | policyID |     PolicyStartDate     |    IncidentDatetime     |  NotificationDatetime   |           Version            |
+---------+----------------+----------+-------------------------+-------------------------+-------------------------+------------------------------+
|     223 |            259 |       48 | 2015-06-01 00:00:00.000 | 2015-11-03 00:00:00.000 | 2015-11-20 00:00:00.000 | 4. Claim - Incident Date     |
|      30 |            287 |       48 | 2015-06-01 00:00:00.000 | 2015-11-06 00:00:00.000 | 2015-11-27 00:00:00.000 | 4. Claim - Incident Date     |
|    1367 |            988 |       48 | 2015-06-01 00:00:00.000 | 2016-04-15 00:00:00.000 | 2016-04-21 00:00:00.000 | 4. Claim - Incident Date     |
|    1742 |            991 |       48 | 2015-06-01 00:00:00.000 | 2016-04-20 00:00:00.000 | 2016-04-21 00:00:00.000 | 4. Claim - Incident Date     |
|    1561 |           1859 |       49 | 2016-06-01 00:00:00.000 | 2016-09-14 00:00:00.000 | 2016-09-19 00:00:00.000 | 4. Claim - Incident Date     |
|    1741 |         443275 |       48 | 2015-06-01 00:00:00.000 | 2016-05-11 00:00:00.000 | 2016-05-12 00:00:00.000 | 4. Claim - Incident Date     |
|    3744 |            259 |       48 | 2015-06-01 00:00:00.000 | 2015-11-03 00:00:00.000 | 2015-11-20 00:00:00.000 | 5. Claim - Notification Date |
|    2038 |            287 |       48 | 2015-06-01 00:00:00.000 | 2015-11-06 00:00:00.000 | 2015-11-27 00:00:00.000 | 5. Claim - Notification Date |
|    4639 |            988 |       48 | 2015-06-01 00:00:00.000 | 2016-04-15 00:00:00.000 | 2016-04-21 00:00:00.000 | 5. Claim - Notification Date |
|    3745 |            991 |       48 | 2015-06-01 00:00:00.000 | 2016-04-20 00:00:00.000 | 2016-04-21 00:00:00.000 | 5. Claim - Notification Date |
|    4502 |           1859 |       49 | 2016-06-01 00:00:00.000 | 2016-09-14 00:00:00.000 | 2016-09-19 00:00:00.000 | 5. Claim - Notification Date |
|    6600 |         443275 |       48 | 2015-06-01 00:00:00.000 | 2016-05-11 00:00:00.000 | 2016-05-12 00:00:00.000 | 5. Claim - Notification Date |
+---------+----------------+----------+-------------------------+-------------------------+-------------------------+------------------------------+

答案 2 :(得分:0)

根据收到的建议,我可以调整查询以提供所需的结果。这是我的最终参考代码:

 <td><input name="invqty[]" type="text" onchange="SetDefault(<?php echo $cnt; ?>, $(this).val());" onkeyup="this.onchange();" onpaste="this.onchange();" oninput="this.onchange();" class="form-control1" id="invqty<?php echo $cnt; ?>" size="5" value="<?php echo $qty; ?>"></td>