2010-07-15 9 views
1

Voici mon problème. Je crée 4 tables temporaires pour compter des types spécifiques de boîtes et les heures d'un employé. Étant donné une date de début et une date de fin, nous voulons connaître le nombre total de cases de chaque type (1, 2 et 3) et le nombre total d'heures travaillées pendant cette période. Tout fonctionne parfaitement s'il y en a au moins un de chaque type, mais si seulement deux types sont présents, j'obtiens un résultat vide pour toute l'instruction SELECT finale. Donc, une instruction SELECT qui contient une table temporaire vide dans la ligne FROM peut-elle faire en sorte que tout le reste soit vide? Par exemple, la plage de dates 6-1-10 à 6-10-10 renvoie 10 boîtes de type 1, 12 boîtes de type 2, 0 boîte de type 3 et 36 heures, mais le résultat affiché est vide. Mais si elle est étendue un jour et 15 cases de type 3 sont incluses, la requête fonctionne.Can SELECTING FROM une table temporaire vide dans SQL provoque les résultats à vide?

SELECT Count(isnull(Box_Num,0)) as Box1, emp_num INTO #Box1 
FROM TEST.dbo.Prod_beta2 
WHERE BoxType like '1' and time > '06/01/10' + ' 12:01 AM' and time < '06/10/10' + ' 11:59pm' and emp_num like '10467' 
group by emp_num 


SELECT Count(isnull(Box_Num,0)) as Box2, emp_num INTO #Box2 
FROM TEST.dbo.Prod_beta2 
WHERE BoxType like '2' and time > '06/01/10' + ' 12:01 AM' and time < '06/10/10' + ' 11:59pm' and emp_num like '10467' 
group by emp_num 


SELECT count(isnull(box_num,0)) as Box3, emp_num INTO #Box3 
from TEST.dbo.Prod_beta2 
WHERE BoxType like '3' and time > '06/01/10' + ' 12:01 AM' and time < '06/10/10' + ' 11:59pm' and emp_num like '10467' 
group by emp_num 


SELECT SUM(HOURS) as TotalHours, empid INTO #Hours 
FROM TEST.dbo.Timeclock 
where timein > '06/01/10' + ' 12:01 AM' and timein < '06/10/10' + ' 11:59pm' and empid like '10467' 
group by empid 


SELECT Box1, Box2, Box3, TotalHours 
FROM #Box1, #Box2, #Box3, #Hours 


DROP TABLE #Box1, #Box2, #Box3, #Hours 
+1

Pourquoi créez-vous tous ces tables temporaires quand vous pourriez tout aussi bien peupler @variables et ensuite les retourner? – DOK

+0

Est-ce que 'empid' et' empnum' sont les mêmes valeurs? Si c'est le cas, cela peut être fait avec une seule requête (et pas de tables temporaires). Vous vous rendez compte que sans critères de jointure, 'SELECT Box1, Box2, Box3, TotalHours DE # Box1, # Box2, # Box3, # Hours' produit un [produit cartésien] (http://www.codinghorror.com/blog/ 2007/10/a-visual-explication-de-sql-joins.html)? –

Répondre

2

Oui. Vous faites un produit cartésien ce qui signifie que vous aurez des lignes B1 * B2 * B3 * H dans le résultat.

Lorsque B3 n'a pas de lignes, vous multipliez évidemment par zéro.

Les trois premières de vos conditions peuvent être facilement combinées (en passant, quel est le type de données de BoxType et emp_num?) Si elles sont numériques, n'utilisez pas de chaînes pour éviter les problèmes de conversion de type inutiles. semble manquer quoi que ce soit entre 23:59-à-0:01. Est-ce intentionnel? de plus, vous devriez probablement utiliser les formats de date ISO pour éviter tout problème si vous changez les serveurs, etc.)

SELECT 
Count(CASE WHEN BoxType = '1' THEN 1 ELSE NULL END) as Box1, 
Count(CASE WHEN BoxType = '2' THEN 1 ELSE NULL END) as Box2, 
Count(CASE WHEN BoxType = '3' THEN 1 ELSE NULL END) as Box3 
FROM TEST.dbo.Prod_beta2 
WHERE BoxType in ('1','2','3') and time > '06/01/10' + ' 12:01 AM' and 
    time < '06/10/10' + ' 11:59pm' and emp_num like '10467' 
group by emp_num 
+1

Vous aviez raison. J'ai ajouté des instructions de jointure pour éliminer la multiplication par zéro et fonctionne comme un charme. Merci –

0

Si les champs sont tous du même type, alors vous ne devriez pas le faire comme ceci:

SELECT Box1, Box2, Box3, TotalHours 
FROM #Box1, #Box2, #Box3, #Hours 

Vous devez utiliser une UNION ALL requête

comme ceci:

SELECT Count(isnull(Box_Num,0)) as Box1, emp_num 
    FROM TEST.dbo.Prod_beta2 
    WHERE BoxType like '1' and time > '06/01/10' + ' 12:01 AM' and time < '06/10/10' + ' 11:59pm' and emp_num like '10467' 
    UNION ALL 
    SELECT Count(isnull(Box_Num,0)) as Box2, emp_num 
    FROM TEST.dbo.Prod_beta2 
    WHERE BoxType like '2' and time > '06/01/10' + ' 12:01 AM' and time < '06/10/10' + ' 11:59pm' and emp_num like '10467' 
    UNION ALL 

SELECT count(isnull(box_num,0)) as Box3, emp_num 
from TEST.dbo.Prod_beta2 
WHERE BoxType like '3' and time > '06/01/10' + ' 12:01 AM' and time < '06/10/10' + ' 11:59pm' and emp_num like '10467' 
group by emp_num 

Votre dernier choix est la seule chose qui diffère, donc séparez cette requête du numéro o f les boîtes étant affichées.

Cependant, vous n'avez même pas besoin de tables temporaires pour cela, utilisez simplement les instructions SELECT standard et ajoutez union à chacune d'entre elles.

Votre instruction actuelle donnera 0 lignes à condition que l'une de ces requêtes contienne 0 lignes. Look into cartesian products and what they mean