【问题标题】:SQL Server 2008 Join by date getting right valuesSQL Server 2008 按日期加入获取正确的值
【发布时间】:2018-02-07 09:05:02
【问题描述】:

我的场景并不难。基本上,我有两个表,我需要通过一个 PK 和一个日期加入它们,问题是薪水表有一个每个月支付的日期,第二个称为奖金的表只有一个必须是年度奖金的日期在宣布年度奖金后的日期与工资挂钩,但直到明年奖金为止。

知道了这一点,您就可以知道这就是您检查表格的方式。 薪资表:

样本数据:

DateHist;NumSalarie;ValeurMontant;ChargePatronal;ChargesSalariales

2012-10-31 00:00:00.000;1;3519;1322;766,49 2012-11-30 00:00:00.000;1;3519;1322;766,49 2012-12-31 00:00:00.000;1;3519;1322;766,49 2013-01-31 00:00:00.000;1;3519;1395,15;867,84 2013-02-28 00:00:00.000;1;3592,33;1936,78;1157,09 2013-03-31 00:00:00.000;1;3592,33;1423,23;882,85 2013-04-30 00:00:00.000;1;3592,33;1423,23;882,85 2013-05-31 00:00:00.000;1;3592,33;1423,23;882,85 2013-06-30 00:00:00.000;1;3592,33;1423,23;882,85 2013-07-31 00:00:00.000;1;3592,33;1423,23;882,85 2013-08-31 00:00:00.000;1;3592,33;1202,4;765,41 2013-09-30 00:00:00.000;1;3592,33;1385,19;862,52 2013-10-31 00:00:00.000;1;3592,33;1423,23;882,85 2013-11-30 00:00:00.000;1;3592,33;1423,23;882,85 2013-12-31 00:00:00.000;1;3592,33;1423,23;882,85 2014-01-31 00:00:00.000;1;3592,33;1439,35;897,52 2014-02-28 00:00:00.000;1;3592,33;1825,8;1104,15 2014-03-31 00:00:00.000;1;3666,67;2858,27;1656,17 2014-04-30 00:00:00.000;1;3666,67;1468,1;912,89 2014-05-31 00:00:00.000;1;3666,67;1468,1;912,89

奖金表:

样本数据:

CodeRubrique;NumSalarie;ValeurMontant;DateHist

1200;1;1267;2013-02-28 00:00:00.000 1200;1;3448,64;2014-03-31 00:00:00.000 1200;1;3633;2015-03-31 00:00:00.000 1200;1;2244;2015-09-30 00:00:00.000 1200;1;4042,84;2016-10-31 00:00:00.000

所以,现在当我在 T-SQL 中加入两个表时:

SELECT 
salpaid.DateHist,
salpaid.NumSalarie,
salpaid.ValeurMontant,
bonus.ValeurMontant AS bonus
FROM
    (select CodeRubrique,NumSalarie,ValeurMontant,DateHist
    FROM table ) salpaid
LEFT JOIN 
    (select CodeRubrique,NumSalarie,ValeurMontant,DateHist
    FROM T_HBNS
    WHERE  CodeRubrique='1200')  bonus
ON salpaid.NumSalarie=bonus.NumSalarie
AND salpaid.DateHist >= bonus.DateHist

所以,这是我的问题。问题是日期加入它是不对的,因为结果是当完成第一年奖金然后我在第一年奖金之后的日期我链接两次。上一年的奖金和现在的奖金。只是为了向你们展示我的输出:

如您所见,第 73 行之前的付款在奖金中为 NULL,因为第一次注册的奖金是在这些日期之后,然后在第 74 行和第 87 行之间是可以的。当我获得第二年奖金时,噩梦就来了,因为我获得了正确奖金类别的链接,但我还有另一个与上一年奖金的链接,正如您在 88 之后的行中看到的那样。

我应该如何改进我的代码以获得正确的 JOIN?

谢谢大家

【问题讨论】:

  • 工资表缺少标题
  • 这是一个很好的起点。 spaghettidba.com/2015/04/24/… 您还应该指定您正在使用的 DBMS 作为 mysql sql server。
  • 样本数据最好以 DDL+DML 的形式提供。图片是最糟糕的。
  • 我添加了@ZoharPeled

标签: sql sql-server sql-server-2008 date join


【解决方案1】:

如果您使用每个奖金的开始日期和结束日期构建 CTE,您可以外连接到 DateHist 位于奖金开始日期和结束日期之间的 cte

WITH Bonus_Ordered AS (
    SELECT  *,
            ROW_NUMBER() OVER (PARTITION BY [NumSalarie] ORDER BY [DateHist]) Rn
    FROM    Bonus
    WHERE   CodeRubrique = '1200' 
),   

Bonus_Periods AS (
    SELECT  a.*, 
            b.DateHist - 1 AS EndDateHist 
    FROM    Bonus_Ordered a LEFT JOIN Bonus_Ordered b ON a.Rn + 1 = b.Rn
)

SELECT  *
FROM    Salary s
        LEFT JOIN Bonus_Periods bp ON s.NumSalarie = bp.NumSalarie 
             AND s.DateHist BETWEEN bp.DateHist AND bp.EndDateHist
ORDER BY s.DateHist

SQL Fiddle example

【讨论】:

  • 好方法,伙计,我知道了,实际上在我在 COALESCE(bp.EndDateHist,getdate()) 之间添加的连接中,保证始终涵盖正确的最新数量!谢谢
  • @AndresAngel 很好。我在测试 cte 时想到了最后一个空日期,但忘记在连接中修复它。 Bonus_Periods cte 可能是放置 coalesce(b.DateHist - 1, getdate()) AS EndDateHist 的更好地方
【解决方案2】:

如果你改变了怎么办

salpaid.DateHist >= bonus.DateHist

年份(salpaid.DateHist) = 年份(bonus.DateHist)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多