2010-03-07 17 views
37

Tengo una tabla con las siguientes columnas: entityId, EntityName, EntityProfile, .................¿Cómo seleccionar verdadero/falso en función del valor de la columna?

deseo seleccionar el identificador y el nombre y verdadero/columna falsa basada en el valor del perfil de la entidad, , por ejemplo, un conjunto de resultados devuelto como se muestra a continuación, significaría que las entidades 1 & 2 tienen perfiles, mientras que 3 no.

1 Name1 True 
2 Name2 True 
3 Name3 False 
etc..... 

sé que puedo hacerlo utilizando una función que devuelven verdadero/falso sobre la base del valor del perfil de esta manera: SELECT EntityId, EntityName, dbo.EntityHasProfile (EntityId) AS HasProfile de entidades

pero Estoy devolviendo un gran no. de registros y con esta función llame para cada registro, la consulta es muy lenta, y cuando elimino la llamada a la función, el tiempo de ejecución de la consulta disminuye significativamente.

¿Hay otra forma de hacerlo? Gracias

+2

Probablemente pueda 'join', pero no nos dijo cómo se calcula 'EntityHasProfile'. ¿Tienes otra mesa? – Kobi

+0

lo siento, me olvidé de mencionar que, el perfil de la entidad es nvarchar (max) – Yasmine

+0

¿Y cómo se utiliza EntityProfile para determinar si EntityHasProfile? Si es nulo ...? – froadie

Respuesta

73

Utilice un CASE. Publicaba el código específico, pero necesito más información de la que se proporciona en la publicación, como el tipo de datos de EntityProfile y lo que generalmente se almacena en él. Algo así como:

CASE WHEN EntityProfile IS NULL THEN 'False' ELSE 'True' END 

Editar - toda la instrucción SELECT, según la información en los comentarios:

SELECT EntityID, EntityName, 
     CASE WHEN EntityProfile IS NULL THEN 'False' ELSE 'True' END AS HasProfile 
FROM Entity 

Sin LEFT JOIN necesario en este caso ...

+0

¿Qué sucede si tengo un 20 y una columna anterior que tiene bit (verdadero/falso) tipo de datos? ¿Puede aplicarse lo mismo? @froadie – Kopika

+2

Para expandir esta respuesta, esto devuelve una picadura de verdadero o falso. Satisface completamente el OP, pero puede ser más útil como un campo de T/F real (como lo menciona Kopika). me gustaría utilizar esta declaración de caso: SELECT EntityID, EntityName, fundido (CASO CUANDO EntityProfile ES NULO ENTONCES 0 1 ELSE END) como bit) AS HasProfile DE Entidad – Rob

+0

@ Rob Gracias por eso. pero el paréntesis se abrió una vez, se cerró dos veces? – Jasir

6

Puede intentar algo así como

SELECT e.EntityId, 
     e.EntityName, 
     CASE 
      WHEN ep.EntityId IS NULL THEN 'False' 
      ELSE 'TRUE' 
     END AS HasProfile 
FROM Entities e LEFT JOIN 
     EntityProfiles ep ON e.EntityID = ep.EntityID 

O

SELECT e.EntityId, 
     e.EntityName, 
     CASE 
      WHEN e.EntityProfile IS NULL THEN 'False' 
      ELSE 'TRUE' 
     END AS HasProfile 

FROM Entities e 
0

Lo que la UDF EntityHasProfile() hacer?

Normalmente, usted podría hacer algo como esto con una combinación izquierda:

SELECT EntityId, EntityName, CASE WHEN EntityProfileIs IS NULL THEN 0 ELSE 1 END AS Has Profile 
FROM Entities 
LEFT JOIN EntityProfiles 
    ON EntityProfiles.EntityId = Entities.EntityId 

Esto debería eliminar la necesidad de una llamada escalar UDF costosa - en mi experiencia, las UDF escalares deben ser el último recurso para la mayoría de diseño de base de datos problemas en SQL Server - simplemente no son buenos actores.

+0

se supone que el udf debe probar el valor del perfil de entidad para el id pasado, si null devuelve falso else devuelve verdadero – Yasmine

4

Si el la manera de determinar si una entidad tiene un perfil o no es una función determinista, y no requiere ningún acceso a otra tabla, puede escribir una función almacenada y definir un campo calculado y persistente que almacenaría ese valor para usted y no tendría para volver a calcularlo una y otra vez.

Si necesita consultar una tabla separada (por ejemplo, verificar la existencia de una fila), aún podría hacer que esta columna "HasProfile" sea una en su tabla de entidades y simplemente calcular ese campo de forma regular, p. Ej. cada noche más o menos. Si tiene el valor almacenado como un valor atómico, no necesita el cálculo cada vez. Esto funciona siempre que ese hecho - tenga un perfil o no - no cambie con demasiada frecuencia.

Para agregar una columna para comprobar si es o no EntityProfile está vacía, hacer algo como esto:

CREATE FUNCTION CheckHasProfile(@Field VARCHAR(MAX)) 
RETURNS BIT 
WITH SCHEMABINDING 
AS BEGIN 
    DECLARE @Result BIT 

    IF @Field IS NULL OR LEN(@Field) <= 0 
     SET @Result = 0 
    ELSE 
     SET @Result = 1 

    RETURN @Result 
END 

y luego añadir una nueva columna calculada a su mesa Entity:

ALTER TABLE dbo.Entity 
    ADD HasProfile AS dbo.CheckHasProfile(EntityProfile) PERSISTED 

Ahora tener una columna BIT y es persistente, por ejemplo no se computa cada vez para acceder a la fila, ¡y debería funcionar perfectamente!

Cuestiones relacionadas