SQL Left Join - shorter date longer than current date

Asked

Viewed 494 times

1

3 tables: Processo, Evento, Alerta

The goal is to make a query that returns all processes by adding the columns of the most recent event type and date MAX(DataEvento) and the next warning (shorter date longer than the current date) and warning remarks.

SELECT p.id
      ,p.scope
      ,p.entrydate
      ,p.applicant
      ,p.status
      ,MAX(ev.eventdatetime) lastevent
      ,ev.type
      ,ev.eventobs
      ,MIN(al.deadlinedate) nextalert
      ,al.alertobs
  FROM process p
  LEFT JOIN event ev
    ON ev.processid = p.id
  LEFT JOIN alert al
    ON al.eventid = ev.eventid
   AND al.expiredate > getdate()
 GROUP BY p.id
         ,p.scope
         ,p.entrydate
         ,p.applicant
         ,p.status
         ,ev.type
         ,ev.eventobs
         ,al.expiredate
         ,al.alertobs

The above code repeats all processes several times, depending on the number of events.

    SELECT p.id
      ,p.scope
      ,p.entrydate
      ,p.applicant
      ,p.status
      ,MAX(ev.eventdatetime) lastevent
      ,ev.type
      ,ev.eventobs
      ,MIN(al.deadlinedate) nextalert
      ,al.alertobs
  FROM process p
 INNER JOIN event ev
    ON ev.processid = p.id
 INNER JOIN alert al
    ON al.eventid = ev.eventid
 WHERE ev.processid = p.id
   AND a.expiredate > getdate()
 GROUP BY p.id
         ,p.scope
         ,p.entrydate
         ,p.applicant
         ,p.status
         ,ev.type
         ,ev.eventobs
         ,al.alertobs

List only one process, the one that has the most recent event.

SELECT DISTINCT p.id
               ,p.scope
               ,p.entrydate
               ,p.applicant
               ,p.status
               ,(SELECT TYPE
                      ,MAX(ev.eventdatetime) lastevent
                      ,eventobs
                  FROM event ev
                 WHERE ev.processid = p.id
                 GROUP BY TYPE
                         ,eventobs)
               ,(SELECT MIN(a.expiredate) nextalert
                      ,alertobs
                  FROM event ev
                 INNER JOIN alert a
                    ON ev.eventid = a.eventid
                 WHERE ev.processid = p.id
                   AND a.expire > getdate())
  FROM process p
 ORDER BY p.id ASC

Here comes the error:

Only one Expression can be specified in the select list when the subquery is not introduced with EXISTS.

What I want is to list all processes each one appears once and the query fields are presented, adding the date, type and observations of the last event and the date and observations of the next alert, example:

1|Registo|21/06/2018|João Sousa|Activo|21/06/2018|Entrada do processo|Observações do evento|26/06/2018|Prazo para resposta

2|Pedido|21/06/2018|Pedro Antunes|Activo|21/06/2018|Entrada do processo|Observações do evento|26/06/2018|Prazo para resposta
  • passes the table structure please

  • The tables are bigger actually, I simplified here to ask the question...

  • look at this: https://www.db-fiddle.com/f/xzzMqmDGQe6TXFg9LchNqw/0

  • Yes, list correctly, however it is T-SQL and does not have the issue of alert. The alert is associated with the event and each event can have 1 or several alerts, I need to list the lowest alert date higher than the current date. I will try to adapt this solution, I believe that these details cause some confusion in the syntax, when I get put here

2 answers

2

Only use Subselect:

SELECT 
    p.Id, 
    p.Scope, 
    p.EntryDate, 
    p.Applicant, 
    p.Status,
    (SELECT 
         MAX(ev.EventDateTime) 
     FROM event ev 
     WHERE ev.processId = p.id) as evento_recente,
    (SELECT 
         MIN(a.ExpireDate) 
     FROM event ev 
     INNER JOIN Alert a ON ev.eventid = a.eventId 
     WHERE ev.processId = p.id) as proximo_alerta
FROM Process p 
  • 1

    Perfect, all that remained was to compare the date to the current date on this line: (Select MIN(a.Expiredate) from Event Ev Inner Join Alert a on Ev.eventid = a.eventId Where Ev.processid = p.Id and a.Expiredate > GETDATE()) as next. Thank you

  • When I try to load other columns from the selected event or alert it gives the following error: Only one Expression can be specified in the select list when the subquery is not introduced with EXISTS. How can I get over it?

  • you have to see your query, it seems syntax error

  • With left Join I can gather all the columns I want, however, repeats the same process for each event instead of just showing the last one. Modifying the subquery you suggested earlier to include the remaining columns I want gives the error I mentioned. The logic seems to be correct, it’s probably a syntax problem yes, but I’m having trouble solving despite having already consulted several seemingly similar examples

  • @OMB edits your question, asks how your query is now and an example of the data that is returning, and an example of how it should return

  • Edited. The subquery solution you suggested before fits perfectly as long as you can also add the event type and observations and the warning notes, but I’m not matching the syntax to do so.

  • @OMB you did not put an example of how the data is... but I think just use the Distinct : SELECT DISTINCT
 p.Id, ...

  • Assuming there are n events in process 1, this process is listed n times, one for each event. I’ve tried using Distict, it doesn’t work...

  • see if this is the same problem: https://answall.com/q/308450/69359

  • Exactly, same problem, I’ll see if any solution fits me

Show 5 more comments

0


Minor adjustments may be necessary as I have not yet tested whether the dates loaded are always correct, but it will never be very different from the list I get with the code below:

 SELECT p.id
      ,p.scope
      ,p.entrydate
      ,p.applicant
      ,p.status
      ,ev.type
      ,ev.eventdatetime AS lastevent
      ,ev.eventobs
      ,MIN(al.expiredate) nextalert
      ,al.alertobs
  FROM process p
  LEFT OUTER JOIN event ev
    ON ev.processid = p.id
   AND ev.eventid = (SELECT top(1) eventid
                       FROM event e
                      WHERE e.processid = ev.processid
                      ORDER BY e.eventdatetime DESC)
  LEFT OUTER JOIN alert al
    ON al.processid = p.id
   AND al.alertid =
       (SELECT top(1) alertid
          FROM alert a a.deadlinedate > getdate())
 GROUP BY p.id
         ,p.scope
         ,p.entrydate
         ,p.applicant
         ,p.status
         ,ev.type
         ,ev.eventdatetime
         ,ev.eventobs
         ,al.alertobs

Thank you so much @Rovann Linhalis for the precious help.

  • right, usually query questions without the tables and no sample records get a bit confusing... always put this data and if possible mount a Sqlfiddle... helps a lot...; For nothing, whenever the community needs help =]

  • Yeah, I’ll remember that next time!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.