Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 多次连接到同一个表时的条件连接和查询优化_Sql_Sql Server_Query Optimization - Fatal编程技术网

Sql 多次连接到同一个表时的条件连接和查询优化

Sql 多次连接到同一个表时的条件连接和查询优化,sql,sql-server,query-optimization,Sql,Sql Server,Query Optimization,我们的数据库中有两个表。查询中的主表是Asset。它与名为AssetListing的表具有一对多关系。 AssetListing表中有多个日期和数字字段,我们当前有一个报告,用于获取每个日期中的一个,在某些情况下,还可以从AssetListing表中获取日期不为空的数值。需要注意的是,在每种情况下,如果特定日期不为空,我们都希望获得与最近的AssetListingId(AssetListing上的PK)关联的日期。查询当前如下所示: SELECT A.AssetNumber ,

我们的数据库中有两个表。查询中的主表是Asset。它与名为AssetListing的表具有一对多关系。 AssetListing表中有多个日期和数字字段,我们当前有一个报告,用于获取每个日期中的一个,在某些情况下,还可以从AssetListing表中获取日期不为空的数值。需要注意的是,在每种情况下,如果特定日期不为空,我们都希望获得与最近的AssetListingId(AssetListing上的PK)关联的日期。查询当前如下所示:

SELECT A.AssetNumber
        , CLP.CurrentListPrice
, CLP.CurrentListPriceDate
, ListingExpirationDate = LXP.ExpirationDate
, LPC.ListPriceChange
, LPC.ListPriceChangeDate
FROM Asset A
LEFT JOIN
    (
        SELECT AssetNumber
            , AssetListingId
            , CurrentListPrice
            , CurrentListPriceDate
            , ROW_Num = ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC)
        FROM [dbo].AssetListing WITH (NOLOCK)
        WHERE CurrentListPrice IS NOT NULL
    ) CLP ON CLP.AssetNumber = A.AssetNumber AND CLP.ROW_NUM = 1
LEFT JOIN
    (
        SELECT AssetNumber
            , AssetListingId
            , ExpirationDate
            , ROW_Num = ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC)
        FROM [dbo].AssetListing WITH (NOLOCK)
        WHERE ExpirationDate IS NOT NULL
    ) LXP ON LXP.AssetNumber = A.AssetNumber AND LXP.ROW_NUM = 1
LEFT JOIN
    (
        SELECT AssetNumber
            , AssetListingId
            , CurrentListPrice
            , ListPriceChange
            , ListPriceChangeDate
            , ROW_Num = ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC)
        FROM [dbo].AssetListing WITH (NOLOCK)
        WHERE ListPriceChange IS NOT NULL
    ) LPC ON LPC.AssetNumber = A.AssetNumber AND LPC.ROW_NUM = 1
必须有一种方法可以通过一个连接来实现这一点,但我不确定如何进行。 我们需要每个连接的日期,在某些情况下,我们还需要一个数值。
如何优化此查询?

试试看,这样做的目的是最大限度地利用基于行号的每个资产编号应该只有一个结果

SELECT A.AssetNumber
    , CurrentListPrice      = MAX(CASE WHEN CPRN = 1 THEN CurrentListPrice END)
    , CurrentListPriceDate  = MAX(CASE WHEN CPRN = 1 THEN CurrentListPriceDate END)
    , ListingExpirationDate = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
    , ListPriceChange       = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
    , ListPriceChangeDate   = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
FROM Asset A
JOIN (
    SELECT AssetNumber
        , AssetListingId
        , CurrentListPrice
        , CurrentListPriceDate
        , ExpirationDate
        , ListPriceChange
        , ListPriceChangeDate
        , CPRN = CASE WHEN CurrentListPrice IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
        , EPRN = CASE WHEN ExpirationDate IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
        , LPRN = CASE WHEN ListPriceChange IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
    FROM dbo.AssetListing WITH (NOLOCK)
) AL ON AL.AssetNumber = A.AssetNumber
GROUP BY A.AssetNumber

实际上,连接在这里看起来没有必要,但我把它留了下来,以防有一些简化。

试试看,这样做的想法是,根据行号,每个资产编号最多只能有一个结果

SELECT A.AssetNumber
    , CurrentListPrice      = MAX(CASE WHEN CPRN = 1 THEN CurrentListPrice END)
    , CurrentListPriceDate  = MAX(CASE WHEN CPRN = 1 THEN CurrentListPriceDate END)
    , ListingExpirationDate = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
    , ListPriceChange       = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
    , ListPriceChangeDate   = MAX(CASE WHEN EPRN = 1 THEN ExpirationDate END)
FROM Asset A
JOIN (
    SELECT AssetNumber
        , AssetListingId
        , CurrentListPrice
        , CurrentListPriceDate
        , ExpirationDate
        , ListPriceChange
        , ListPriceChangeDate
        , CPRN = CASE WHEN CurrentListPrice IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
        , EPRN = CASE WHEN ExpirationDate IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
        , LPRN = CASE WHEN ListPriceChange IS NOT NULL 
                      THEN ROW_NUMBER() OVER (PARTITION BY AssetNumber ORDER BY AssetListingId DESC) END
    FROM dbo.AssetListing WITH (NOLOCK)
) AL ON AL.AssetNumber = A.AssetNumber
GROUP BY A.AssetNumber
连接在这里看起来并没有必要,但我把它留了下来,以防万一会有一些简化