I have a query where I am using IN clause (for 2 columns, 251 and 252) to get records from tables. In ideal case, either 251 or 252 will have value, so it should work fine, but in some cases, some jobs may have both 251 or 252 value, but I need to only limit 1 record based on jobHistoryID (max value). With below query, I get sometimes 2 and if I use Top 1 in Left Join, it gets me 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
You can add a ROW_NUMBER()
function based on the 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
but i think you can optimize you query as the following:
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
Perhaps you can LEFT JOIN The history table and take the first record ordered by date.
;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
It seems that you have done many rewritings into your query in order to make it work and you have introduced some redundancy (ie redundant join with tblJob
in the most inner subquery). Try the following query to make it work.
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
Use 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]
You'll also notice that this removes the JOIN
to tblJob
in the subquery, because that is not really necessary.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.