在表中查找最后更新的行

时间:2018-10-23 14:09:17

标签: sql sql-server

我有两个表(MSSQL):

SELECT 
    [BaseTable].[datasource_id]
    ,[BaseTable].[datasource_filter_column]
    ,[BaseTable].[dt record_date]
FROM 
    [BaseTable]

此表包含数据源的每日记录及其仅标记为过滤器列的列。

并且:

SELECT
    [CalcTable].[datasource_id]
    ,[CalcTable].[column_name]
    ,[CalcTable].[column_calculation_formula]
    ,[CalcTable].[dt record_date]
FROM
    [CalcTable]

此表包含数据源及其内容的每日记录。

请考虑以下数据:

[BaseTable]

datasource_id   datasource_filter_column    dt record_date
1234abc             column1                     18-Oct-18
1234abc             column1                     20-Oct-18
1234abc             column1                     21-Oct-18
1234abc             column1                     23-Oct-18

[CalcTable]

datasource_id   column_name     column_calculation_formula      dt record_date
1234abc         column1         CONCAT('first ','entry')          18-Oct-18
1234abc         column1         CONCAT('second ','entry')         20-Oct-18
1234abc         column1         CONCAT('third ','entry')          21-Oct-18
1234abc         column1         CONCAT('third ','entry')          23-Oct-18

我需要以三种不同的方式将[CalcTable]加入[BaseTable]上。 (两个表中的日期可能并不总是相同,因为它们可以在不同的日期进行更新。)

(我可以得到的这部分)
我需要从[dt record_date]中提取[first_record_date](AS [column_calculation_formula])及其对应的[first_calculation_formula](AS [CalcTable]),这将是包含最早{与[CalcTable].[dt record_date]匹配的{1}}。

(我可以得到的这部分)
[BaseTable].[datasource_id], [BaseTable].[column_name]的{​​{1}}(AS [dt record_date])及其对应的[latest_record_date](AS [column_calculation_formula]),该行将是包含最新[latest_calculation_formula]的行与[CalcTable]匹配。 (这两个很容易获得。)

(我无法获得这部分)
我还需要获取[CalcTable].[dt record_date](AS [BaseTable].[datasource_id], [BaseTable].[column_name])及其对应的[dt record_date](AS [previous_record_date])。
这将是包含与[column_calculation_formula]匹配但与[previous_calculation_formula]条目的[CalcTable].[dt record_date]不匹配的最新[BaseTable].[datasource_id], [BaseTable].[column_name]的行。

我经历了多次尝试,并将自己与sub sub sub选择混淆,并加入了wazoo。 我可以毫无问题地得到开始和结束的细节,它主要是最后更新的部分,这让我很生气。我敢肯定,它比我想做的要简单得多。 任何帮助将不胜感激。

联接的预期结果:

[column_calculation_formula]

2 个答案:

答案 0 :(得分:1)

我认为类似的东西应该可以工作,尽管我还没有真正测试过它。 加号可能不能很好地执行,您可能想要添加一些WHERE子句内容?

select 
  base.Datasource_id, 
  base.DataSource_Name, 
  first_entry_date = firstsub.entryDate,
  first_calculation_formula = firstsub.column_calculation_formula,
  last_entry_date = lastsub.entryDate,
  last_calculation_formula = lastsub.column_calculation_formula,
  previous_entry_date = previoussub.entryDate,
  previous_calculation_formula = previoussub.column_calculation_formula
from 
  BaseTable base
  OUTER APPLY 
  ( 
    select top 1 
      entryDate = ct.dt_record_date,
      ct.column_calculation_formula
    from 
      Calctable ct
    where
      ct.DataSource_id=base.Datasource_id
      and ct.column_name=base.column_name
      and ct.column_caption=base.column_caption
    order by ct.dt_record_date 
  ) firstsub
  OUTER APPLY 
  ( 
    select top 1 
      entryDate = ct.dt_record_date,
      ct.column_calculation_formula
    from 
      Calctable ct
    where
      ct.DataSource_id=base.Datasource_id
      and ct.column_name=base.column_name
      and ct.column_caption=base.column_caption
    order by ct.dt_record_date desc
  ) lastsub   
  OUTER APPLY 
  ( 
    select top 1 
      entryDate = ct.dt_record_date,
      ct.column_calculation_formula
    from 
      Calctable ct
    where
      ct.DataSource_id=base.Datasource_id
      and ct.column_name=base.column_name
      and ct.column_caption=base.column_caption
      and (ct.column_calculation_formula <> lastsub.column_calculation_formula)
    order by ct.dt_record_date desc
  ) previoussub   

答案 1 :(得分:0)

对,我想我知道了。
我一直在按照jarlh关于top 1有序desc的评论进行思考,但是知道在记录日期将不起作用。因此,我选择了按[column_calculation_formula] desc排序的前1个[dt record_date],并选择了MAX([dt record_date])不等于[column_calculation_formula]的{​​{1}}。 /> 我最终得到的代码如下:

WITH [Updated] AS (
SELECT
    [1].[datasource_id]
    ,[1].[column_name]
    ,[1].[column_calculation_formula]
    ,[1].[dt record_date]
FROM 
    [CalcTable] [1]
WHERE 
    [1].[dt record_date] = (
        SELECT 
            MAX([2].[dt record_date]) 
        FROM 
            [CalcTable] [2] 
        WHERE 
            [2].[datasource_id] = [1].[datasource_id] 
            AND [2].[column_name] = [1].[column_name] 
            AND  [2].[column_calculation_formula] <> (
                SELECT TOP 1
                    [3].[column_calculation_formula]
                FROM 
                    [CalcTable] [3] 
                WHERE
                    [3].[datasource_id] = [2].[datasource_id] 
                    AND [3].[column_name] = [2].[column_name] 
                ORDER BY [dt record_date] DESC
                                                    )
                            )
GROUP BY 
    [1].[datasource_id]
    ,[1].[column_name]
    ,[1].[column_calculation_formula]
    ,[1].[dt record_date]
)
,[Latest] AS 
(
SELECT
    [1].[datasource_id]
    ,[1].[column_name]
    ,[1].[column_calculation_formula]
    ,[1].[dt record_date]
FROM 
    [CalcTable] [1]
WHERE 
    [1].[dt record_date] = (
    SELECT 
        MAX([2].[dt record_date]) 
    FROM 
        [CalcTable] [2] 
    WHERE 
        [2].[datasource_id] = [1].[datasource_id]
        AND [2].[column_name] = [1].[column_name]
                        )
GROUP BY 
    [1].[datasource_id]
    ,[1].[column_name]
    ,[1].[column_calculation_formula]
    ,[1].[dt record_date]
)
,[Earliest] AS 
(
SELECT
    [1].[datasource_id]
    ,[1].[column_name]
    ,[1].[column_calculation_formula]
    ,[1].[dt record_date]
FROM 
    [CalcTable] [1]
WHERE 
    [1].[dt record_date] = (
    SELECT 
        MIN([2].[dt record_date]) 
    FROM 
        [CalcTable] [2] 
    WHERE 
        [2].[datasource_id] = [1].[datasource_id]
        AND [2].[column_name] = [1].[column_name]
        )
GROUP BY 
    [1].[datasource_id]
    ,[1].[column_name]
    ,[1].[column_calculation_formula]
    ,[1].[dt record_date]
)
, [Filters] AS
(
SELECT 
    [datasource_id]
    ,[datasource_filter_column]
    ,[dt record_date]
FROM 
    [BaseTable]
WHERE
    [dt record_date] = (
    SELECT 
        MAX([dt record_date]) 
    FROM 
        [BaseTable] [2] 
    WHERE 
        [2].[datasource_id] = [BaseTable].[datasource_id]
        AND [2].[datasource_filter_column] = [BaseTable].[datasource_filter_column]
        )

GROUP BY 
    [datasource_id]
    ,[datasource_filter_column]
    ,[dt record_date]

)

SELECT 
    [Filters].[datasource_id]
    ,[Filters].[datasource_filter_column]
    ,[Earliest].[column_calculation_formula] AS [first_calculation_formula]
    ,[Earliest].[dt record_date] AS [first_record_date]
    ,[Updated].[column_calculation_formula] AS [previous_calculation_formula]
    ,[Updated].[dt record_date] AS [previous_record_date]
    ,[Latest].[column_calculation_formula] AS [latest_calculation_formula]
    ,[Latest].[dt record_date] AS [latest_record_date]
FROM 
    [Filters]

LEFT JOIN [Latest] ON
    [Latest].[datasource_id] = [Filters].[datasource_id]
    AND [Latest].[column_name] = [Filters].[datasource_filter_column]
    AND LEN(TRIM([Latest].[column_calculation_formula])) > 0

LEFT JOIN [Earliest] ON
    [Earliest].[datasource_id] = [Filters].[datasource_id]
    AND [Earliest].[column_name] = [Filters].[datasource_filter_column]
    AND LEN(TRIM([Earliest].[column_calculation_formula])) > 0

LEFT JOIN [Updated] ON
    [Updated].[datasource_id] = [Filters].[datasource_id]
    AND [Updated].[column_name] = [Filters].[datasource_filter_column]
    AND LEN(TRIM([Updated].[column_calculation_formula])) > 0

GROUP BY 
    [Filters].[datasource_id]
    ,[Filters].[datasource_filter_column]
    ,[Earliest].[column_calculation_formula]
    ,[Earliest].[dt record_date]
    ,[Updated].[column_calculation_formula]
    ,[Updated].[dt record_date]
    ,[Latest].[column_calculation_formula]
    ,[Latest].[dt record_date]

任何改进建议将不胜感激。