Pergunta

Eu tenho uma consulta que deve retornar a soma de entradas -Duração "status". A duração é calculada usando datediff (n, data-hora, (subconsulta que retorna do carimbo datador terminando o estado actual, isto é encontra da próxima encaixe "mudança de estado" -Entrada depois a uma bloqueada no)

Meu problema é que a consulta a seguir retorna um erro identificador de várias partes

  • A tabela INC está me dando o "INCIDENT_NUMBER" eu estou procurando wich está relacionada com "Número" nas outras tabelas
  • ACTM1 detém todo DATESTAMP-entradas
  • ACTA1 está relacionada com ACTM1 via "oNumero" e que detém todas as informações sobre se uma entrada é uma mudança de status apropriado ou não

Código:

SELECT SUM(DATEDIFF(n, ACTM1.DATESTAMP, END_DATESTAMP_TABLE.END_DATESTAMP))
FROM INC                LEFT OUTER JOIN
  ACTM1   ON INC.INCIDENT_NUMBER = ACTM1.NUMBER  LEFT OUTER JOIN
  ACTA1   ON ACTM1.THENUMBER  = ACTA1.THENUMBER  LEFT OUTER JOIN
/**/
    (SELECT  ACTM1_1.NUMBER, ACTM1_1.DATESTAMP AS END_DATESTAMP
  FROM ACTM1 AS ACTM1_1               LEFT OUTER JOIN
/**/
      (SELECT ACTM1_1_1.NUMBER, MIN(ACTM1_1_1.THENUMBER) AS FOLLOWUP_THENUMBER
    FROM ACTM1 AS ACTM1_1_1
    WHERE  (ACTM1_1_1.THENUMBER > /**/ ACTM1_1.THENUMBER)/*I think here lies the problem*/
      AND (ACTM1_1_1.[TYPE]  IN ('Open', 'Status Change', 'Resolved', 'Closed')))
    AS FOLLOWUP_THENUMBER_TABLE
/**/
            ON ACTM1_1.NUMBER = FOLLOWUP_THENUMBER_TABLE.NUMBER)
  AS END_DATESTAMP_TABLE
/**/
            ON ACTM1.NUMBER = END_DATESTAMP_TABLE.NUMBER
WHERE ...

Eu ficaria grato por qualquer comentário útil ou dica que você poderia me dar sobre este assunto,

PS

Foi útil?

Solução

O lado esquerdo juntar a relação não pode referenciar o lado direito, então isso é ilegal:

SELECT ...
FROM A
JOIN (SELECT ...FROM ... WHERE ... = A.Field) AS B ON A.ID = B.ID;

Use o operador aplicar em seu lugar:

SELECT ...
FROM A
APPLY (SELECT ...FROM ... WHERE ... = A.Field AND ID = A.ID) AS B;

No seu caso provavelmente seria como seguir:

SELECT SUM(DATEDIFF(n, ACTM1.DATESTAMP, END_DATESTAMP_TABLE.END_DATESTAMP))
FROM INC                
LEFT OUTER JOIN ACTM1 ON INC.INCIDENT_NUMBER = ACTM1.NUMBER  
LEFT OUTER JOIN ACTA1 ON ACTM1.THENUMBER  = ACTA1.THENUMBER  
LEFT OUTER JOIN (
   SELECT  ACTM1_1.NUMBER, ACTM1_1.DATESTAMP AS END_DATESTAMP
   FROM ACTM1 AS ACTM1_1
   OUTER APPLY (
      SELECT ACTM1_1_1.NUMBER, /* MIN(ACTM1_1_1.THENUMBER) */ AS FOLLOWUP_THENUMBER
        FROM ACTM1 AS ACTM1_1_1
        WHERE  (ACTM1_1_1.THENUMBER > ACTM1_1.THENUMBER)
        AND (ACTM1_1.NUMBER = FOLLOWUP_THENUMBER_TABLE.NUMBER)
        AND (ACTM1_1_1.[TYPE]  IN ('Open', 'Status Change', 'Resolved', 'Closed'))
    ) AS FOLLOWUP_THENUMBER_TABLE
) AS END_DATESTAMP_TABLE ON ACTM1.NUMBER = END_DATESTAMP_TABLE.NUMBER

Obviamente, o MIN dentro da consulta interna não faz sentido embora.

Outras dicas

Eu reescrever a consulta para não usar subconsultas em tudo:

SELECT
     SUM(DATEDIFF(n, A1.datestamp, A2.datestamp))

FROM
     INC AS I
INNER JOIN ACTM1 AS A1 ON
     A1.number = INC.incident_number
INNER JOIN ACTM1 AS A2 ON
     A2.number > A1.number AND
     A2.type IN ('Open', 'Status Change', 'Resolved', 'Closed')
LEFT OUTER JOIN ACTM1 AS A3 ON
     A3.number > A1.number AND
     A3.type IN ('Open', 'Status Change', 'Resolved', 'Closed') AND
     A3.number < A2.number
WHERE
     A3.number IS NULL

Eu não era capaz de projetar totalmente inversa a sua declaração. Eu não sei se você precisava de esquerda junta-se ou não, e eu não vi onde ACTA1 foi realmente sendo usado, então eu deixei-o para fora. Como resultado, pode ser necessário ajustar o acima. A idéia geral é que para encontrar uma linha com um número maior, que tem o tipo que você precisa, mas para os quais não há outra linha (A3) com o tipo certo e um número que cai entre os dois números.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top