从另一个表中联接最新日期和属于该日期的其他字段

时间:2019-08-07 11:50:32

标签: sql-server sql-server-2012

我想加入另一个具有DATE值的表,并且只希望添加最新的Date和与该Date相对应的最新Value。

我有一张表,其中RENTALOBJECTTABLE中的某些RENTALOBJECTS与OBJECTTABLE的关系为N:1

RENTALOBJECTTABLE:
RENTALOBJECTID, OBJECTID
1,              1
2,              1
3,              2
4,              3
5,              4
6,              4


OBJECTTABLE:
OBJECTID
1
2
3
4

每个OBJECTID都可以(通常通常超过1个)VALUE

VALUETABLE:
OBJECTID,   VALUE,  VALIDFROM,  VALIDTO,    CODE
1,          2000,   1-1-1950,   31-12-1980, A
1,          3000,   1-1-1981,   31-12-2010, A
1,          4000,   1-1-2013,   NULL,       A
2,          1000,   1-1-1970,   NULL,       A
3,          2000,   1-1-2010,   NULL,       A
4,          2000,   1-1-2000,   31-12-2009, A
4,          3100,   1-1-2010,   NULL,       B
4,          3000,   1-1-2010,   NULL,       A

并结合在一起,我希望为每个RentalObject显示最新的VALUE。预期最终结果:

RENTALOBJECTTABLE_WITHVALUE:
RENTALOBJECTID, OBJECTID,   VALUE,  VALIDFROM,  VALIDTO,    CODE
1,              1,          4000,   1-1-2013,   NULL,       A
2,              1,          4000,   1-1-2013,   NULL,       A
3,              2,          1000,   1-1-1970,   NULL,       A
4,              3,          2000,   1-1-2010,   NULL,       A
5,              4,          3000,   1-1-2010,   NULL,       A
6,              4,          3000,   1-1-2010,   NULL,       A

到目前为止,我设法通过以下代码将“最近日期”加入到表中。但是,只要我要包含VALUETABLE.VALUE,行数就会从5000(原始数据集具有的行数)变为48000。

SELECT
RENTALOBJECTTABLE.RENTALOBJECTID
FROM RENTALOBJECTTABLE
LEFT JOIN OBJECTTABLE
    ON OBJECTTABLE.OBJECTID = RENTALOBJECTTABLE.OBJECTID
LEFT JOIN (
    SELECT 
        OBJECTID,
        CODE,
        VALUE, --without this one it gives the same rows as the original table
        MAX(VALIDFROM) VALIDFROM
    FROM VALUETABLE
    LEFT JOIN PMETYPE 
        ON VALUETABLE.CODE = PMETYPE.RECID
        AND PMETYPE.REGISTERTYPENO = 6
        WHERE PMETYPE.[NAME] = 'WOZ'
    GROUP BY OBJECTID, CODE, VALUE
    ) VALUETABLE ON OBJECTTABLE.OBJECTID = VALUETABLE.OBJECTID

当我在MAX(Date)旁边添加MAX(VALUE)时,显然又有原始的5000个数据集行,但是现在它仅选择最近的日期+最大值,这并不总是正确的。

关于如何解决此问题的任何线索吗? 我想我很想念一些东西。

2 个答案:

答案 0 :(得分:1)

您的样本数据

weather = forecast('api_key',lat, -long)
windbearing = weather.windBearing
windspeed = float(weather.windSpeed)

def windcompass(windbearing):
    val = int((windbearing/22.5)+.5)
    argument = ["N","NNE","NE","ENE","E","ESE", "SE", "SSE","S","SSW","SW","WSW","W","WNW","NW","NNW"]
    return argument[(val % 16)]

direction = windcompass(windbearing)

print('The wind is blowing ', + windspeed, + 'at ', + direction, + 'MPH')

查询:

select * into #RENTALOBJECTTABLE from (
SELECT 1 AS RENTALOBJECTID, 1 OBJECTID
UNION ALL SELECT 2,1
UNION ALL SELECT 3,2
UNION ALL SELECT 4,3
UNION ALL SELECT 5,4
UNION ALL SELECT 6,4) A


SELECT * INTO #OBJECTTABLE FROM(
SELECT 
1 OBJECTID
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4)AS B



SELECT * INTO #VALUETABLE FROM (
SELECT   1OBJECTID,2000 VALUE,'1-1-1950'VALIDFROM,'31-12-1980' VALIDTO, 'A' CODE
UNION ALL SELECT 1,3000,'1-1-1981','31-12-2010', 'A'
UNION ALL SELECT 1,4000,'1-1-2013',NULL,       'A'
UNION ALL SELECT 2,1000,'1-1-1970',NULL,       'A'
UNION ALL SELECT 3,2000,'1-1-2010',NULL,       'A'
UNION ALL SELECT 4,2000,'1-1-2000','31-12-2009', 'A'
UNION ALL SELECT 4,3100,'1-1-2010',NULL,       'B'
UNION ALL SELECT 4,3000,'1-1-2010',NULL,       'A'
) AS C

输出数据:

;WITH CTE AS (
SELECT * , ROW_NUMBER()OVER(PARTITION BY OBJECTID ORDER BY OBJECTID DESC)RN FROM #VALUETABLE
)
SELECT RO.RENTALOBJECTID,RO.OBJECTID,C.VALUE,C.VALIDFROM,C.VALIDTO,C.CODE
FROM CTE C 
CROSS APPLY (SELECT OBJECTID,MAX(RN)RN FROM CTE C1 WHERE C.OBJECTID=C1.OBJECTID GROUP BY OBJECTID )AS B
INNER JOIN #RENTALOBJECTTABLE RO ON RO.OBJECTID=C.OBJECTID
WHERE  C.OBJECTID=B.OBJECTID AND C.RN=B.RN

答案 1 :(得分:1)

这可以让你关闭

WITH cte AS
(
    SELECT 
        o.OBJECTID,
        v.VALUE,
        v.VALIDFROM,
        v.VALIDTO,
        v.CODE,
        ROW_NUMBER() OVER (PARTITION BY o.OBJECTID ORDER BY v.VALIDFROM DESC ) rn
    FROM dbo.OBJECTTABLE o 
    INNER JOIN dbo.VALUETABLE v ON v.OBJECTID = o.OBJECTID
)
SELECT ro.RENTALOBJECTID,
       ro.OBJECTID,
       cte.OBJECTID,
       cte.VALUE,
       cte.VALIDFROM,
       cte.VALIDTO,
       cte.CODE
FROM dbo.RENTALOBJECTTABLE ro 
INNER JOIN cte ON cte.OBJECTID = ro.OBJECTID
    AND rn=1;

但是,这可能会拉出对象4的3100值-没有什么可以使用相同的validfrom来分隔两个值。如果在值表中具有(或可以添加)标识列,则可以按顺序在分区上使用该列,以选择所需的行。