Sql查询IN子句限制1条记录

Sql Query IN clause limit 1 Record

我有一个查询,我在其中使用 IN 子句(对于 2 列,251 和 252)从表中获取记录。在理想情况下,251 或 252 都有值,因此它应该可以正常工作,但在某些情况下,某些作业可能同时具有 251 或 252 值,但我只需要根据 jobHistoryID(最大值)限制 1 条记录。通过下面的查询,我有时会得到 2,如果我在 Left Join 中使用 Top 1,它会得到 null

SELECT 
    [Job].[JobID],
    [Job].[PriceEstimateNumber],
    [CustomerReadyDate].[JobHistoryDate] As [ConfirmLeadDate1],
    [CustomerReadyDate].[JobColumnID]
FROM
    [tblJob] Job
        ON [Job].[JobID] = [StepJob].[JobID]
        AND [Job].[SubmitTimestamp] > '2019-01-01'
    LEFT JOIN (
            SELECT 
                [JobHistory].[JobID],
                [JobHistory].[JobHistoryDate],
                [JobHistory].[JobColumnID],
                [JobHistory].[JobHistoryID],
            FROM [dbo].[tblJob_History] AS [JobHistory]
            INNER JOIN [dbo].[tblJob] AS [Job]
                ON [Job].[JobID] = [JobHistory].[JobID] 
            WHERE
                [JobHistory].[jobColumnID] IN (251,252)      
            ) AS [CustomerReadyDate]
            ON [CustomerReadyDate].[JobID] = [Job].[JobID]

WHERE
    [Job].[OrderType] = 'Job'
    AND [Job].LocationTypeID = 1

您可以在 jobHistoryID

的基础上添加一个 ROW_NUMBER() 函数
SELECT 
    [Job].[JobID],
    [Job].[PriceEstimateNumber],
    [CustomerReadyDate].[JobHistoryDate] As [ConfirmLeadDate1],
    [CustomerReadyDate].[JobColumnID]
FROM
    [tblJob] Job
        ON [Job].[JobID] = [StepJob].[JobID]
        AND [Job].[SubmitTimestamp] > '2019-01-01'
    LEFT JOIN (
            SELECT 
                [JobHistory].[JobID],
                [JobHistory].[JobHistoryDate],
                [JobHistory].[JobColumnID],
                [JobHistory].[JobHistoryID],
                ROW_NUMBER() OVER(ORDER BY [JobHistoryID] DESC) rn
            FROM [dbo].[tblJob_History] AS [JobHistory]
            INNER JOIN [dbo].[tblJob] AS [Job]
                ON [Job].[JobID] = [JobHistory].[JobID] 
            WHERE
                [JobHistory].[jobColumnID] IN (251,252)      
            ) AS [CustomerReadyDate]
            ON [CustomerReadyDate].[JobID] = [Job].[JobID]

WHERE
    [Job].[OrderType] = 'Job'
    AND [Job].LocationTypeID = 1
    AND [CustomerReadyDate].rn = 1

但我认为您可以优化您的查询,如下所示:

SELECT * FROM (

    SELECT 
        [Job].[JobID],
        [Job].[PriceEstimateNumber],
        [JobHistory].[JobHistoryDate] As [ConfirmLeadDate1],
        [JobHistory].[JobColumnID]
        ROW_NUMBER() OVER(ORDER BY [JobHistoryID] DESC) rn
    FROM [dbo].[tblJob_History] AS [JobHistory]
    INNER JOIN [dbo].[tblJob] AS [Job]
        ON [Job].[JobID] = [JobHistory].[JobID] 
    WHERE [JobHistory].[jobColumnID] IN (251,252)   
    AND [Job].[OrderType] = 'Job'
    AND [Job].LocationTypeID = 1

) AS T1

WHERE T1.rn = 1 

也许您可以 LEFT JOIN 历史 table 并获取按日期排序的第一条记录。

;WITH Data AS
(
    SELECT 
            [Job].[JobID],
            [Job].[PriceEstimateNumber],
            [CustomerReadyDate].[JobHistoryDate] As [ConfirmLeadDate1],
            [CustomerReadyDate].[JobColumnID],
            Instance = ROW_NUMBER() OVER(PARTITION BY Job.JobId ORDER BY [CustomerReadyDate.JobHistoryDate] DESC)
        FROM
            [tblJob] Job
                ON [Job].[JobID] = [StepJob].[JobID]
                AND [Job].[SubmitTimestamp] > '2019-01-01'
             LEFT JOIN [dbo].[JobHistory] AS [CustomerReadyDate]
                        ON [Job].[JobID] = [CustomerReadyDate].[JobID]  AND [CustomerReadyDate].[jobColumnID] IN (251,252)     
        WHERE
            [Job].[OrderType] = 'Job'
            AND [Job].LocationTypeID = 1

)
SELECT
   JobID,
   ConfirmLeadDate1,
   JobColumnID
FROM
    Data D
WHERE
    Instance = 1    

您似乎对查询进行了多次重写以使其正常工作,并且引入了一些冗余(即在最内部子查询中使用 tblJob 进行冗余连接)。尝试以下查询使其工作。

SELECT *
FROM (
    SELECT 
        [Job].[JobID],
        [Job].[PriceEstimateNumber]
        [JobHistory].[JobHistoryDate],
        [JobHistory].[JobColumnID],
        row_number() over (partition by [Job].[JobID] order by [JobHistory].[JobHistoryID] desc) AS [rn]
    FROM [dbo].[tblJob_History] AS [JobHistory]
    INNER JOIN [dbo].[tblJob] AS [Job]
        ON [Job].[JobID] = [JobHistory].[JobID] 
    WHERE
        [JobHistory].[JobColumnID] IN (251,252) AND
        [Job].[SubmitTimestamp] > '2019-01-01' AND
        [Job].[OrderType] = 'Job' AND 
        [Job].LocationTypeID = 1
) t
WHERE t.[rn] = 1

使用OUTER APPLY:

FROM [tblJob] Job
     ON [Job].[JobID] = [StepJob].[JobID] AND
        [Job].[SubmitTimestamp] > '2019-01-01' OUTER APPLY
    (SELECT TOP (1) [JobHistory].[JobID], [JobHistory].[JobHistoryDate],
            [JobHistory].[JobColumnID], [JobHistory].[JobHistoryID],
     FROM [dbo].[tblJob_History] [JobHistory] 
     WHERE [Job].[JobID] = [JobHistory].[JobID] AND 
           [JobHistory].[jobColumnID] IN (251, 252)
     ORDER BY JobHistory.JobHistoryId DESC      
    ) [CustomerReadyDate]

您还会注意到,这会删除子查询中的 JOINtblJob,因为这并不是真正必要的。