Estoy usando SQL Server 2016 y los datos que estoy consumiendo tienen el siguiente formulario.
CREATE TABLE #tab (cat CHAR(1), t CHAR(2), val1 INT, val2 CHAR(1));
INSERT INTO #tab VALUES
('A','Q1',2,NULL),('A','Q2',NULL,'P'),('A','Q3',1,NULL),('A','Q3',NULL,NULL),
('B','Q1',5,NULL),('B','Q2',NULL,'P'),('B','Q3',NULL,'C'),('B','Q3',10,NULL);
SELECT *
FROM #tab;
Me gustaría obtener los últimos valores no nulos sobre las columnas val1
y val2
agruparlos cat
y ordenarlos por t
. El resultado que estoy buscando es
cat val1 val2 A 1 P B 10 C
Lo más cerca que he venido es usar LAST_VALUE
mientras ignoro lo ORDER BY
que no va a funcionar ya que necesito el último valor no nulo ordenado.
SELECT DISTINCT
cat,
LAST_VALUE(val1) OVER(PARTITION BY cat ORDER BY (SELECT NULL) ) AS val1,
LAST_VALUE(val2) OVER(PARTITION BY cat ORDER BY (SELECT NULL) ) AS val2
FROM #tab
cat val1 val2 A NULL NULL B 10 NULL
La tabla real tiene más columnas para cat
( columnas de fecha y cadena) y más columnas val (columnas de fecha, cadena y número) para seleccionar el último valor no nulo.
Alguna idea de cómo hacer esta selección.
sql-server
window-functions
Edmund
fuente
fuente
cat
ordenado port
.t
valores se repiten. No se trata de datos bien comportados.PARTITION BY cat ORDER BY t, id
por ejemplo. De lo contrario, la misma consulta (cualquier consulta) puede brindarle resultados diferentes en ejecuciones separadas. Si las columnas en la tabla son solo las que muestra, ¡no veo cómo podemos tener un orden determinado!Respuestas:
El uso de la técnica de concatenación de The Last non NULL Puzzle de Itzik Ben Gan se vería así con su tabla de muestra y tipos de datos de columna.
Otra forma de escribir esta consulta que divide los pasos en CTE para quizás mostrar mejor lo que está sucediendo. Da exactamente el mismo plan de ejecución que la consulta anterior.
Esta solución utiliza el hecho de que concatenar un valor nulo con algo da como resultado un valor nulo. SET CONCAT_NULL_YIELDS_NULL (Transact-SQL)
fuente
Simplemente agregue un cheque para NULL en la partición hará
fuente
Esto debería hacerlo. row_number () y una unión
Si no tiene un buen tipo, debe esperar que solo uno de los Q3 no sea nulo.
fuente