0

I apologize if the title for the question doesn't match what I am asking what to do. I am not sure how to describe what I am trying to accomplish.

I have the following tables in my database:

Table customers
    customer_id (PK, int, NN)
    customer_name (varchar(100), NN)

Table jobs
    job_id (PK, int, NN)
    job_number (varchar(10), NN)
    job_description (varchar(MAX), NN)
    customer_id (FK, int, NN)

Table job_statuses
    status_id (PK, int, NN)
    status_description (varchar(50), NN)

Table job_status_logs
    log_id (PK, int, NN)
    job_id (FK, int, NN)
    status_id (FK, int, NN)
    log_date (date, NN)

Now I am trying to program a procedure where I pass it a Job Number and it does the following:

1) Checks if the Job Number exists within the database, if not, return an error message.

2) If the Job Number exists return the following columns from the following tables:

jobs: job_id, job_number, job_description
customers: customer_name
job_status_logs: log_date (WHERE status_description is 'Open') & log_date (WHERE status_description is 'Closed')

I am mainly having an issue with the very last part, as I am unsure how to form the query looking for the last two points of data (the ones from the job_status_logs table).

EDIT: This is currently what I have for the procedure

CREATE PROCEDURE dbo.GetJobData(
    @JobNum   VARCHAR(10),
    @response NVARCHAR(500) OUTPUT
) AS
BEGIN
    DECLARE @JobID INT
    SELECT @JobID = job_id
      FROM jobs
     WHERE job_number = @JobNum
    IF @JobID IS NULL
    BEGIN
        SET @response = 'Cannot find data for Job "' + @JobNum + '".  Job does not exist.'
        RETURN
    END
    SELECT j.job_id AS [ID], j.job_number AS [Job], j.job_description AS [Description], c.customer_name AS [Customer]
      FROM jobs AS j INNER JOIN
           customer AS c ON c.customer_id = j.customer_id
     WHERE j.job_id = @JobID
END
GO

As stated above, I do not know how to set up the query to grab the data I am looking for from the job_status_logs table.

6
  • 2
    Please edit the question and show what you have tried so far.
    – Peter B
    Commented Nov 2, 2018 at 12:27
  • @PeterB my question is that I literally don't know how to formulate the query to get the data I am looking for. So me posting what I have tried, is me posting what in my question I said I already know how to do. Commented Nov 2, 2018 at 12:30
  • Did you mean status_description instead of status_id in the last WHERE clause you provided? Because status_id is integer and you are trying to compare it with strings such as Open or Close. Commented Nov 2, 2018 at 12:37
  • @BahtiyarSametÇoban yes, I did mean description, will edit that Commented Nov 2, 2018 at 12:38
  • @Skitzafreak - what do you want to see if the job was opened, but never closed? Is that possible? Commented Nov 2, 2018 at 13:13

2 Answers 2

1

Try this - there are two examples. The first result (jobid=100) has both and open and a closed logdate. The second result (jobid=200) only has an open logdate. Take note of the LEFT JOIN against the 'closed' statuses.

--demo setup
DECLARE @customers TABLE (
    customer_id INT
    ,customer_name VARCHAR(100)
    )
insert into @customers(customer_id,customer_name) values(1,'bob')

DECLARE @jobs TABLE (
    job_id INT
    ,job_number VARCHAR(10)
    ,job_description VARCHAR(MAX)
    ,customer_id INT
    )
insert into @jobs(job_id,job_number,job_description,customer_id) values
(1,'100','jobdesc',1),(2,'200','jobdesc2',1)

DECLARE @job_statuses TABLE (
    status_id INT
    ,status_description VARCHAR(50)
    )
insert into @job_statuses(status_id,status_description) values(1,'open'),(2,'closed')

DECLARE @job_status_logs TABLE (
    log_id INT
    ,job_id INT
    ,status_id INT
    ,log_date DATE
    )
insert into @job_status_logs(log_id, job_id,status_id,log_date) values
(1,1,1,'2018-10-01'),(2,1,2,'2018-11-01'),(3,2,1,'2018-12-01')

--the solution
--parameter passed into SP
DECLARE @JobNumber INT

SET @JobNumber = 100    --has both open and closed status

SELECT j.job_id
    ,j.job_number
    ,j.job_description
    ,c.customer_name
    ,jslo.log_date AS LogOpen
    ,jslc.log_date AS LogClosed
FROM @jobs j
JOIN @customers c
    ON c.customer_id = j.customer_id
JOIN (
    SELECT jsl.job_id
        ,log_date
    FROM @job_status_logs jsl
    JOIN @job_statuses js
        ON js.status_id = jsl.status_id
            AND js.status_description = 'open'
    ) jslo
    ON jslo.job_id = j.job_id
LEFT JOIN (
    SELECT jsl.job_id
        ,log_date
    FROM @job_status_logs jsl
    JOIN @job_statuses js
        ON js.status_id = jsl.status_id
            AND js.status_description = 'closed'
    ) jslc
    ON jslc.job_id = j.job_id
WHERE j.job_number = @JobNumber

---------------------------

SET @JobNumber = 200    --has only open status

SELECT j.job_id
    ,j.job_number
    ,j.job_description
    ,c.customer_name
    ,jslo.log_date AS LogOpen
    ,jslc.log_date AS LogClosed
FROM @jobs j
JOIN @customers c
    ON c.customer_id = j.customer_id
JOIN (
    SELECT jsl.job_id
        ,log_date
    FROM @job_status_logs jsl
    JOIN @job_statuses js
        ON js.status_id = jsl.status_id
            AND js.status_description = 'open'
    ) jslo
    ON jslo.job_id = j.job_id
LEFT JOIN (
    SELECT jsl.job_id
        ,log_date
    FROM @job_status_logs jsl
    JOIN @job_statuses js
        ON js.status_id = jsl.status_id
            AND js.status_description = 'closed'
    ) jslc
    ON jslc.job_id = j.job_id
WHERE j.job_number = @JobNumber

Result1

| job_id | job_number | job_description | customer_name | LogOpen    | LogClosed  |
|--------|------------|-----------------|---------------|------------|------------|
| 1      | 100        | jobdesc         | bob           | 2018-10-01 | 2018-11-01 |

Result2

| job_id | job_number | job_description | customer_name | LogOpen    | LogClosed |
|--------|------------|-----------------|---------------|------------|-----------|
| 2      | 200        | jobdesc2        | bob           | 2018-12-01 | NULL      |
1
  • Thank you very much. I didn't know you could join a subquery, so that's something new I learned today :) Commented Nov 2, 2018 at 14:02
0

I believe you meant status_description instead of status_id in the last sentence. Your need is really unclear to me still, I think you want to return one column in the result set and it will be either [OpenDate] or [ClosedDate] according to job status description.

I have deleted my procedure and added necessary changes to your existing procedure. Now, it return a column either [OpenDate] or [ClosedDate].

CREATE PROCEDURE dbo.GetJobData(
    @JobNum   VARCHAR(10),
    @response NVARCHAR(500) OUTPUT
) AS
BEGIN
    DECLARE @JobID INT
    SELECT @JobID = job_id
      FROM jobs
     WHERE job_number = @JobNum
    IF @JobID IS NULL
    BEGIN
        SET @response = 'Cannot find data for Job "' + @JobNum + '".  Job does not exist.'
        RETURN
    END


    IF EXISTS(SELECT 1 FROM jobs j INNER JOIN customers c on j.customer_id=c.customer_id 
    INNER JOIN job_status_logs jl on j.job_id=jl.job_id
    INNER JOIN job_statuses js on jl.status_id=js.status_id
    where j.job_number=@JobNum
    and js.status_description ='Open')
    BEGIN
    SELECT j.job_id, j.job_number, j.job_description,c.customer_name
    ,jl.log_date as [OpenDate] 
    FROM jobs j
    inner JOIN customers c on j.customer_id=c.customer_id 
    inner JOIN job_status_logs jl on j.job_id=jl.job_id
    inner JOIN job_statuses js on jl.status_id=js.status_id
    where j.job_number=@JobNum
    and js.status_description ='Open' 
    END
    IF EXISTS(SELECT 1 FROM jobs j INNER JOIN customers c on j.customer_id=c.customer_id 
    INNER JOIN job_status_logs jl on j.job_id=jl.job_id
    INNER JOIN job_statuses js on jl.status_id=js.status_id
    where j.job_number=@JobNum
    and js.status_description ='Closed')
    BEGIN
    SELECT j.job_id, j.job_number, j.job_description,c.customer_name
    ,jl.log_date as [ClosedDate] 
    FROM jobs j
    inner JOIN customers c on j.customer_id=c.customer_id 
    inner JOIN job_status_logs jl on j.job_id=jl.job_id
    inner JOIN job_statuses js on jl.status_id=js.status_id
    where j.job_number=@JobNum
    and js.status_description ='Closed' 
    END
END
GO
4
  • You made a correct assumption for my typo, which I fixed in the OP. The issue I am having, is I am not looking for just when status_description is Equal to 'Open' or 'Closed'. I specifically need to select the entry for 'Open' AND the entry for 'Closed'. Commented Nov 2, 2018 at 12:47
  • so you want to understand whether it is open or closed for a job number you are sending to procedure, am I correct? If that is the case, i will update the procedure with union all case. Commented Nov 2, 2018 at 13:00
  • If you see the edit I made to the OP to include what I currently have for the procedure, I essentially want to be able to output a column named 'OpenDate' with the date where the status_description is 'Open' and a column named 'CloseDate' where the status_description is 'Closed'. Commented Nov 2, 2018 at 13:06
  • I edited your SP to return 1 column only as you wanted. If you want to return two columns (OpenDate and CloseDate) for each job result set, this needs to be edited again. Commented Nov 2, 2018 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.