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

时间:2019-01-28 20:47:05

标签: sql sql-server tsql limit

我有一个查询,我在哪里使用IN子句(用于2列251和252)从表中获取记录。在理想情况下,251或252都将具有值,因此它应该可以正常工作,但是在某些情况下,某些作业可能同时具有251或252值,但是我只需要基于jobHistoryID(最大值)限制1条记录。在下面的查询中,有时会得到2,如果我在“左联接”中使用前1,则会得到空值

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

4 个答案:

答案 0 :(得分:3)

您可以基于ROW_NUMBER()添加一个jobHistoryID函数

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 

答案 1 :(得分:0)

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

;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    

答案 2 :(得分:0)

为了使查询正常工作,您似乎已经对查询做了很多重写,并且引入了一些冗余(即,在最内部的子查询中使用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

答案 3 :(得分:0)

使用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]

您还将注意到,这在子查询中将JOIN删除为tblJob,因为这并不是必须的。