2010-04-21 12 views
52

Aquí está mi consulta simple. Si consulto un registro que no existe, no obtendré nada. Preferiría que se devuelva falso (0) en ese escenario. Buscando el método simplista para no tener registros.Devuelve un valor si no se encuentran filas SQL

SELECT CASE 
      WHEN S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1) THEN 1 
      ELSE 0 
     END AS [Value] 

     FROM Sites S 

     WHERE S.Id = @SiteId 

Respuesta

39
SELECT CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END AS [Value] 

FROM Sites S 

WHERE S.Id = @SiteId and S.Status = 1 AND 
     (S.WebUserId = @WebUserId OR S.AllowUploads = 1) 
4

No hay coincidencia de coincidencia significa que no se ha devuelto ningún registro. No hay lugar para el "valor" de 0 si no se encuentran registros. Podrías crear una loca consulta de UNIÓN para hacer lo que quieras, pero mucho, mucho, mucho mejor simplemente para verificar el número de registros en el conjunto de resultados.

+0

Actualmente, eso es lo que hago. Verifique que el recuento de registros esté vacío o no. Supuse que podrían haber sido una forma de atajar mi cheque. – Matt

73

Esto es similar a Adam Robinson, pero usa ISNULL en lugar de COUNT.

SELECT ISNULL(
(SELECT 1 FROM Sites S 
WHERE S.Id = @SiteId and S.Status = 1 AND 
     (S.WebUserId = @WebUserId OR S.AllowUploads = 1)), 0) 

Si la consulta interna tiene una fila coincidente, se devuelve 1. La consulta externa (con ISNULL) luego devuelve este valor de 1. Si la consulta interna no tiene una fila coincidente, entonces no devuelve nada. La consulta externa trata esto como un NULL, por lo que el ISNULL termina devolviendo 0.

+0

¡Gracias por agregar este! Es exactamente lo que necesito, ya que podría SELECCIONAR ISNULL ((¡SELECCIONAR Id ... en lugar de 1 para obtener los datos que estaba buscando! –

+0

Muy tarde, lo sé, pero puedes reemplazar ISNULL con COALESCE para obtener el mismo resultado . – BlueChippy

+0

Adquirí el hábito de usar COALESCE en lugar de ISNULL porque, desde la memoria (los hábitos mueren mucho), ISNULL no está disponible en SQL Lite o como se llame que se ejecuta en dispositivos Windows Mobile anteriores. COALESCE funciona tanto en lite, Express como en Full SQL. – Ads

9

Esto podría ser un caballo muerto, otra forma de devolver 1 fila cuando no existen filas es UNIÓN otra consulta y mostrar resultados cuando no existe en la mesa.

SELECT S.Status, COUNT(s.id) AS StatusCount 
FROM Sites S 
WHERE S.Id = @SiteId 
GROUP BY s.Status 
UNION ALL --UNION BACK ON TABLE WITH NOT EXISTS 
SELECT 'N/A' AS Status, 0 AS StatusCount 
WHERE NOT EXISTS (SELECT 1 
    FROM Sites S 
    WHERE S.Id = @SiteId 
) 
+2

Utilicé un método similar al intentar obtener totales de una consulta. Simplemente hice una unión con una consulta que devolvía 0 ('SELECT 0'), luego hice un' SUM' en la unión. Simple y fácil de seguir – cjbarth

+2

Si devuelve 2 filas, ¿se garantiza que las filas se devolverán en el orden esperado? –

+0

Y es pesado en el plan de ejecución – Fandango68

6

Algo así como:

if exists (select top 1 * from Sites S where S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1)) 
    select 1 
else 
    select 0 
+0

Utilicé esta solución porque tiene más sentido para mí (tradicionalmente no soy un usuario de SQL). Sin embargo, estoy usando SQL Server, encontré que al agregar el nombre de columna a esto, redondeé este solución muy bien. es decir, después de 'seleccionar 1' y 'seleccionar 2' agregué 'como ' – Harvey

3

Sólo hay que sustituir el DONDE con una combinación izquierda:

SELECT CASE 
     WHEN S.Id IS NOT NULL AND S.Status = 1 AND ...) THEN 1 
     ELSE 0 
    END AS [Value] 

    FROM (SELECT @SiteId AS Id) R 
    LEFT JOIN Sites S ON S.Id = R.Id 

Esta solución le permite devolver los valores predeterminados para cada columna también, por ejemplo:

SELECT 
    CASE WHEN S.Id IS NULL THEN 0 ELSE S.Col1 END AS Col1, 
    S.Col2, 
    ISNULL(S.Col3, 0) AS Col3 
FROM 
    (SELECT @Id AS Id) R 
    LEFT JOIN Sites S ON S.Id = R.Id AND S.Status = 1 AND ... 
5

Leí todas las respuestas aquí, y me llevó un tiempo averiguar qué estaba pasando. Lo siguiente se basa en la respuesta por Moe Sisko y alguna investigación relacionada

Si su consulta SQL no devuelve ningún dato, no hay un campo con un valor nulo, por lo que ni ISNULL ni COALESCE funcionarán como usted lo desee. Mediante el uso de una consulta secundaria, la consulta de nivel superior obtiene un campo con un valor nulo, y tanto ISNULL como COALESCE funcionarán como usted lo desee o espere.

Mi consulta

select isnull(
(select ASSIGNMENTM1.NAME 
from dbo.ASSIGNMENTM1 
where ASSIGNMENTM1.NAME = ?) 
, 'Nothing Found') as 'ASSIGNMENTM1.NAME' 

Mi consulta con los comentarios

select isnull(
--sub query either returns a value or returns nothing (no value) 
(select ASSIGNMENTM1.NAME 
from dbo.ASSIGNMENTM1 
where ASSIGNMENTM1.NAME = ?) 
--If there is a value it is displayed 
--If no value, it is perceived as a field with a null value, 
--so the isnull function can give the desired results 
, 'Nothing Found') as 'ASSIGNMENTM1.NAME' 
0

Esto podría ser una manera.

SELECT TOP 1 [Column Name] FROM (SELECT [Column Name] FROM [table] 
    WHERE [conditions] 
    UNION ALL 
    SELECT 0)A ORDER BY [Column Name] DESC 
1

¿Qué pasa con WITH TIES?

SELECT TOP 1 WITH TIES tbl1.* FROM 
     (SELECT CASE WHEN S.Id IS NOT NULL AND S.Status = 1 
         AND (S.WebUserId = @WebUserId OR 
          S.AllowUploads = 1) 
        THEN 1 
        ELSE 0 AS [Value] 
     FROM Sites S 
     WHERE S.Id = @SiteId) as tbl1 
ORDER BY tbl1.[Value] 
Cuestiones relacionadas