En ciertas ocasiones es necesario extraer de una tabla cuales son los números “continuos” de Facturas o de números de documentos. Esto es útil particularmente por razones de auditoría y de BI. La siguiente consulta realiza dicha operación:

SELECT Principio.NumeroFactura, MIN(final.NumeroFactura)
FROM (SELECT n1.NumeroFactura
FROM dbo.Facturas AS n1
LEFT JOIN dbo.Facturas AS n2
ON n1.NumeroFactura=n2.NumeroFactura+1
WHERE n2.NumeroFactura IS NULL) AS Principio
JOIN (SELECT n1.NumeroFactura
FROM dbo.Facturas AS n1
LEFT JOIN dbo.Facturas AS n2
ON n1.NumeroFactura=n2.NumeroFactura1
WHERE n2.NumeroFactura IS NULL) AS Final
ON Principio.NumeroFactura <=Final.NumeroFactura
GROUP BY Principio.NumeroFactura

La consulta puede ser intimidante al principio pero en realidad solo usa dos técnicas básicas. La primera técnica puede encontrarse en las sub-consultas internas. Analice la sub-consulta:

SELECT n1.NumeroFactura
FROM dbo.Facturas AS n1
LEFT JOIN dbo.Facturas AS n2
ON n1.NumeroFactura=n2.NumeroFactura+1
WHERE n2.NumeroFactura IS NULL

Se puede ver que usa la combinación de un LEFT JOIN de la tabla con ella misma y un IS NULL para producir los inicios de bloques de facturas. Note que el ON usa NumeroFactura+1 o sea traducido de SQL a español podría ser: liste los NumeroFactura que no tienen (IS NULL) un número anterior consecutivo (ON n1.NumeroFactura=2.NumeroFactura+1). Esta técnica ser repite en la otra subconsulta pero usando un -1, por lo que obtiene los números que no tiene números posteriores consecutivos.

La segunda técnica se emplea para unir estas dos consultas, ya que no tiene ningún elemento identificador en común, por lo que la técnica básicamente une la factura inicial del rango escogiendo el Final del bloque de facturas como la más pequeña de las facturas finales que sea mayor o igual a el mismo. Eliminando las sub-consultas puede leerse:

SELECT Principio.NumeroFactura, MIN(final.NumeroFactura)
FROM Principio
JOIN Final
ON Principio.NumeroFactura <=Final.NumeroFactura
GROUP BY Principio.NumeroFactura

Esta consulta funciona en cualquier versión de SQL (7.0, 2000, 2005 y 2008). Pero en 2005 y 2008 puede hacerse más legible cuando se usan CTEs:

;WITH Principio AS (

    SELECT n1.NumeroFactura

    FROM dbo.Facturas AS n1

    LEFT JOIN dbo.Facturas AS n2

    ON n1.NumeroFactura=n2.NumeroFactura+1

    WHERE n2.NumeroFactura IS NULL)

, Final AS (

    SELECT n1.NumeroFactura

    FROM dbo.Facturas AS n1

    LEFT JOIN dbo.Facturas AS n2

    ON n1.NumeroFactura=n2.NumeroFactura1

    WHERE n2.NumeroFactura IS NULL)

SELECT Principio.NumeroFactura, MIN(final.NumeroFactura)

FROM Principio

JOIN Final

ON Principio.NumeroFactura <=Final.NumeroFactura

GROUP BY Principio.NumeroFactura

 

0 Shares:
Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

You May Also Like
Leer más

Expresiones, parámetros y funciones en Azure Data Factory

Hay ocasiones, cuando estamos construyendo pipelines con Azure Data Factory, que queremos repetir patrones para extraer y procesar la información cambiando de manera dinámica, en tiempo de ejecución, valores, orígenes/destinos de los datasets, incluso los mismos linked services. Esto es posible mediante el uso de parámetros, expresiones y funciones. Vamos a ver cómo implementarlo con un ejemplo práctico en el que se nos plantea el siguiente supuesto. Se nos ha pedido que extraigamos todos los días los datos del día anterior de distintas tablas del DW a ficheros en un blob storage que además se nombre como la tabla de origen. Si no pudiéramos utilizar contenido dinámico tendríamos que crear dos datasets (uno de origen y otro de destino) y añadir una actividad de copia por cada tabla a exportar.