2009-06-08 10 views
1

Une interface utilisateur (avant que le rapport montre) montre un coup d'oeil vers le haut (Combo) qui aTSQL Hack nécessaire pour obtenir un filtre pour les données

  • (ID = 0) .Toutes Organisation Unités
  • (ID = 4) .HR
  • (ID = 5) .DEV

Je dois:

  1. Pouvoir afficher les données de (4) + (5) si (0) est sélectionné.
  2. Seulement (4) OU (5) si HR ou DEV est sélectionné.

Recherche code combo (le paramètre sélectionné Flux dans la requête ci-dessous.)


Select 0 AS ID,'All Org' AS Name from DP_ORG_OrganizationUnit 
where DP_ORG_OrganizationUnit.Code IN {AccessData} 
Union 
SELECT 
DP_ORG_OrganizationUnit.ID, 
DP_ORG_OrganizationUnit.Name 
FROM DP_ORG_OrganizationUnit where DP_ORG_OrganizationUnit.Code IN ('HR','DEV') 


données Rapport ligne requête


SET CONCAT_NULL_YIELDS_NULL OFF 

DECLARE @EmpID as int; 
DECLARE @OrganizationUnit as int; 
DECLARE @StartDate as datetime; 
DECLARE @EndDate as datetime; 

SET @EmpID = ?; 
SET @StartDate = ?; 
SET @EndDate = ?; 
SET @OrganizationUnit = ?; 

SELECT 
Employee.Code, 
Employee.Name1+' '+Employee.Name2+' '+Employee.Name3+' '+Employee.Name4+' '+Employee.Name5 AS FullName, 
Employee.OrganizationUnit, 
ContractType.Name, 
EmployeeContract.StartDate, 
EmployeeContract.EndDate 
FROM Employee INNER JOIN (ContractType INNER JOIN EmployeeContract 
ON ContractType.ID = EmployeeContract.ContractType) 
ON Employee.ID = EmployeeContract.Employee 
WHERE (Employee.ID = @EmpID OR @EmpID=0) 
AND 
(Employee.OrganizationUnit = @OrganizationUnit OR @OrganizationUnit=0) 
AND NOT((EndDate < @StartDate or StartDate > @EndDate)); 

De toute façon je peux réaliser des regards de celui-ci? 0 = 0 afficherait également toutes les données des autres départements ..

Personne: -o?

+1

en apprendre davantage sur est ISNULL() et COALESCE(), parce que "SET CONCAT_NULL_YIELDS_NULL OFF" va disparaître dans le futur –

+0

lorsque vous mettez un KEY = x OU Key = y dans le WHERE, balayage de la table de surveillance. –

Répondre

2

Tout d'abord, votre recherche code combo pourrait être resserré un peu:

-- the FROM clause was superfluous 
SELECT 0 AS ID,'All Org' AS Name 
UNION ALL 
-- the two-part identifiers were superfluous (only one table) 
SELECT ID, Name 
FROM DP_ORG_OrganizationUnit 
WHERE Code IN ('HR','DEV') 

Pour la requête de rapport, la forme la plus simple serait:

WHERE 
    ((@OrganizationUnit > 0 AND Employee.OrganizationUnit = @OrganizationUnit) OR 
    (@OrganizationUnit = 0 AND Employee.OrganizationUnit IN (4,5))) 
0

quelque chose comme cela devrait fonctionner

Where (Employee.OrganizationUnit = case when @OrganizationUnit=0 then 4 else @OrganizationUnit end OR case when @OrganizationUnit=0 then 5 else @OrganizationUnit end) 
0

Que diriez-vous

WHERE (Employee.ID = @EmpID OR @EmpID=0) 
AND 
(Employee.OrganizationUnit BETWEEN ISNULL(NULLIF(@OrganizationUnit,0),0) AND ISNULL(NULLIF(@OrganizationUnit,0),99)) 
AND NOT((EndDate < @StartDate or StartDate > @EndDate)); 
+0

Syntaxe incorrecte près du mot clé "BETWEEN". – abmv

+0

Syntaxe corrigée –

0

Essayez ce qui devrait utiliser les index sur votre requête ...

DECALRE @FilterValues (FilterValue int not null primary key) 

IF @Param=0 
BEGIN 
    INSERT INTO @FilterValues VALUES (4) 
    INSERT INTO @FilterValues VALUES (5) 
END 
ELSE ID @PAram IS NOT NULL 
BEGIN 
    INSERT INTO @FilterValues VALUES (@Param) 
END 

SELECT 
    .... 
    FROM YourTable    y 
     INNER JOIN @FilterValues f ON y.Value=f.Value 
    WHERE ..... 
0

version de KM fonctionnera, mais cette requête n'a pas besoin d'une table temporaire ...

SELECT * 
FROM Employee 
WHERE (
     @OrganizationUnit = 0 
     OR 
     (
      @OrganizationUnit <> 0 
      AND 
      Employee.OrganizationUnit = @OrganizationUnit 
     ) 
    ) 
+0

faire cela sur une table de million de lignes et vous souhaiterez que vous ayez une table temporaire pendant que vous numérisez le tout! –

+0

Je veux vous croire, mais pouvez-vous me montrer pourquoi la température ambiante est meilleure? J'ai testé cela sur une table en ligne 500k, mon chemin s'est avéré être d'environ 5% à 10% plus rapide. Peut-être que lorsque le nombre de rangées augmente, le mien devient plus inefficace? Je suis vraiment curieux de savoir lequel est le meilleur. Le plan de requête sur le mien dit: 1. Sélectionnez Coût 2% 2. Filtre Coût 18% 3. Indice de numérisation Coût 80% Votre plan de requête dit: 1. Sélectionnez Coût 0% 2. Hash Match (Inner Join) Coût 53% 3a. Clustered Index Scan @FilterValues ​​Coût 1% 3b. Coût de l'analyse de l'index 46% – Jon

+0

Votre version n'utilisera jamais d'index, seulement l'analyse. pour ma version, cela dépendra du nombre de valeurs uniques dans la colonne Employee.OrganizationUnit (et il y a un index dessus), s'il n'y a pas beaucoup de valeurs différentes par rapport aux lignes de la table qu'elle va scanner. cependant, s'il y a beaucoup de valeurs différentes par rapport au nombre de lignes (un bon index), il utilisera cet index. Dans votre exemple, ce n'est pas un bon index et a fait un scan. –

Questions connexes