Filtrado de valores nulos de varias columnas
Frecuentes
Visto 9,310 veces
1
Utilizando SQL Server 2005.
Los datos están en 2 tablas separadas y solo me han dado permisos de escritura.
Los datos se ven así:
DateTime1 | DateTime2
-----------------------
2012-06-01 | 2012-06-01
2012-06-02 | 2012-06-02
2012-06-04 | 2012-06-05
2012-06-02 | NULL
NULL | 2012-06-05
2012-06-04 | 2012-06-05
NULL | NULL
Lo que intento hacer es poder contar valores en los que DateTime1 y DateTime2 contienen valores, DateTime1 contiene una fecha y DateTime2 es NULL, DateTime1 es NULL y DateTime2 contiene valores.
En general, estoy tratando de evitar que DateTime1 sea nulo y DateTime2 sea nulo.
My sin que importe declaración se ve así:
Where (DateTime1 is not null or DateTime2 is not null)
El único problema es que todavía muestra dónde ambos son valores nulos. Alguien sabe porque puede estar pasando esto o como solucionarlo?
Muchas Gracias
EDITAR Consulta completa según lo solicitado por @Lamak
;With [CTE] As (
Select
TH.ID
,AMT
,Reason
,EffDate
,DateReq
,CS_ID
,ROW_NUMBER()
Over (Partition By ID Order By [pthPrimeKey] Desc) as [RN]
From
DateTime1Table as [MC] (nolock)
Left Join History as [TH] (nolock) on [TH].[ID] = [MC].[ID]
Left Join Trans as [SUB] (nolock) on [SUB].TransactionReasonCode = [TH].Reason
Left Join Renew as [RM] (nolock) on [MC].ID = [RM].ID
Where
([MC].[DateTime1] is not null or [RM].[DateTime2] is not null)
And [PostingDate] = DATEADD(dd, datediff(dd, 1, GetDate()),0)
)
SELECT
[ID]
,[AMT] as [Earned]
,[Reason] as [Reason]
,[EffDate] as [Eff]
,[DateReq] as [Date_Cancel_Req]
,[pthUserId_Number] as [CSR]
FROM [CTE]
Where RN <= 1
1 Respuestas
6
Lo siguiente permitirá incluir filas si
- solo DateTime1 tiene un valor
- solo DateTime2 tiene un valor
- ambos tienen valores
Excluirá las filas donde ambos valores sean NULL. ¿Es eso lo que buscas? (Traté de seguir las conversaciones, pero me perdí, y desearía que tuviera una reproducción más simple con datos de muestra; creo que el CTE y todas las demás uniones y la lógica realmente eliminan el problema real que está teniendo).
WHERE COALESCE([MC].[DateTime1], [RM].[DateTime2]) IS NOT NULL
Sin embargo, dado que está realizando una LEFT OUTER JOIN
, esto puede pertenecer a la ON
cláusula para [RM]
en lugar de WHERE
. De lo contrario, no sabrá si una fila está excluida porque el valor de una fila coincidente era NULL o porque no había una fila coincidente. Y tal vez eso está bien, solo pensé en mencionarlo.
EDITAR
Por supuesto, esa cláusula proporciona exactamente los mismos resultados que...
WHERE ([MC].[DateTime1] is not null or [RM].[DateTime2] is not null)
Quiere una prueba?
DECLARE @a TABLE(id INT, DateTime1 DATETIME);
DECLARE @b TABLE(id INT, DateTime2 DATETIME);
INSERT @a SELECT 1, '20120602' ; INSERT @b SELECT 1, NULL;
INSERT @a SELECT 2, NULL ; INSERT @b SELECT 2, '20120605';
INSERT @a SELECT 3, '20120604' ; INSERT @b SELECT 3, '20120605';
INSERT @a SELECT 4, NULL ; INSERT @b SELECT 4, NULL;
INSERT @a SELECT 5, '20120602' ; INSERT @b SELECT 9, NULL;
INSERT @a SELECT 6, NULL ; INSERT @b SELECT 10, '20120605';
INSERT @a SELECT 7, '20120604' ; INSERT @b SELECT 11, '20120605';
INSERT @a SELECT 8, NULL ; INSERT @b SELECT 12, NULL;
SELECT * FROM @a AS a LEFT OUTER JOIN @b AS b
ON a.id = b.id
WHERE COALESCE(a.DateTime1, b.DateTime2) IS NOT NULL;
SELECT * FROM @a AS a LEFT OUTER JOIN @b AS b
ON a.id = b.id
WHERE a.DateTime1 IS NOT NULL OR b.DateTime2 IS NOT NULL;
Ambas consultas producen:
id DateTime1 id DateTime2
-- ---------- ---- ----------
1 2012-06-02 1 NULL -- because left is not null
2 NULL 2 2012-06-05 -- because right is not null
3 2012-06-04 3 2012-06-05 -- because neither is null
5 2012-06-02 NULL NULL -- because of no match
7 2012-06-04 NULL NULL -- because of no match
Entonces, como sugerí en el comentario, si no está viendo las filas que espera, debe mirar otras partes de la consulta. Si proporciona datos de muestra y los resultados deseados, podemos intentar ayudarlo a reducirlos. Tal como están las cosas, no creo que sepamos lo suficiente sobre su esquema y datos para determinar dónde está el problema.
Respondido el 13 de junio de 12 a las 00:06
No estoy muy seguro de por qué, según los datos de prueba, funciona, pero coalesce funcionó. ¡Gracias! - Brad
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas sql sql-server sql-server-2005 or haz tu propia pregunta.
Tus
WHERE
está bien, el problema debe ser otro. ¿Estás seguro de que los valores son realmenteNULL
?, esas columnas son de tipo datatDATETIME
?, porque puede ser que tengas la cuerda'NULL'
allí - Lamak@GSerg - ¿Por qué?, solo necesita filtrar los resultados donde están ambas columnas
NULL
, y eso es lo queWHERE
está haciendo - Lamak@Lamak Las columnas son DateTime y no es un valor NULL de cadena, es un valor NULL verdadero. - Brad
¿Cómo vas a tener un
ROW_NUMBER()
de menos de 1? (Pista: ¡no lo harás!) - JNK¿Puede prefijar correctamente todas sus columnas para que sepamos de qué tabla proviene cada columna? - Aaron Bertrand