Filtrado de valores nulos de varias columnas

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

preguntado el 12 de junio de 12 a las 19:06

Tus WHERE está bien, el problema debe ser otro. ¿Estás seguro de que los valores son realmente NULL?, esas columnas son de tipo datat DATETIME?, porque puede ser que tengas la cuerda 'NULL' allí -

@GSerg - ¿Por qué?, solo necesita filtrar los resultados donde están ambas columnas NULL, y eso es lo que WHERE está haciendo -

@Lamak Las columnas son DateTime y no es un valor NULL de cadena, es un valor NULL verdadero. -

¿Cómo vas a tener un ROW_NUMBER() de menos de 1? (Pista: ¡no lo harás!) -

¿Puede prefijar correctamente todas sus columnas para que sepamos de qué tabla proviene cada columna? -

1 Respuestas

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 or haz tu propia pregunta.