2010-07-21 6 views
1

J'ai 5 tables et j'essaie de rejoindre en 1 mais je reçois 4 enregistrements pour chacune. Comment puis-je utiliser l'instruction JOIN correcte.Joindre plusieurs tables

SELECT tbl_meter.[cdate] AS 'CDate', 
tbl_meter_backup.[machine_no], 
tbl_machines.[accounting_denomination] AS 'Denom', 
(tbl_meter.[turnover]- tbl_meter_backup.[turnover])* tbl_machines.[accounting_denomination] AS 'Turnover', 
(tbl_meter.[total win]- tbl_meter_backup.[total win])* tbl_machines.[accounting_denomination] AS 'Total win', 
(tbl_meter.[games played]-tbl_meter_backup.[games played]) AS 'Games Played', (tbl_meter.[credit in]-tbl_meter_backup.[credit in]) * tbl_machines.[accounting_denomination] AS 'Credit IN', 
(tbl_meter.[Bill in]-tbl_meter_backup.[Bill in])* tbl_machines.[accounting_denomination] AS 'Bill In', 
(tbl_meter.[cancel credit]-tbl_meter_backup.[cancel credit])* tbl_machines.[accounting_denomination] AS 'Cancel Credit', 
tbl_open_backup.[amount] AS 'cgOpen', 
tbl_cancel_backup.[amount] AS 'cgCancel' 
FROM 
tbl_machines, 
tbl_meter, 
tbl_meter_backup, 
tbl_open_backup, 
tbl_cancel_backup 

INNER JOIN tbl_meter ON 
tbl_meter_backup.[Machine_No] = tbl_meter.[Machine_No] AND tbl_machines.[local_no]=tbl_meter.[machine_no] AND tbl_open_backup.[machine_no]=tbl_meter.[machine_no] AND tbl_cancel_backup.[machine_no]=tbl_meter.[machine_no] 
WHERE tbl_meter_backup.[cDate] = @StartDate AND tbl_meter.[cDate] = @EndDate AND tbl_open_backup.[cdate][email protected] AND tbl_cancel_backup.[cdate][email protected]; 

Répondre

2

Fixez d'abord votre synatx aux jointures explicites qui sont plus faciles à lire et à maintenir, il n'y a aucune excuse pour utiliser une jointure implicite, elles sont sujettes aux erreurs et 18 ans dépassées et particulièrement difficiles à maintenir quand vous les mélangez. Je m'attends à ce que le système ait pu être confus à ce sujet aussi bien que vous n'avez pas fait les jointures correctement. Dans une jointure implicite, le critère de jointure entre dans la clause where et non dans la clause on de la jointure explicite que vous avez utilisée. Vous avez également rejoint à la même table deux fois. Donc, avec les jointures nettoyées, avez-vous toujours un problème de données?

SELECT tbl_meter.[cdate] AS 'CDate', 
tbl_meter_backup.[machine_no], 
tbl_machines.[accounting_denomination] AS 'Denom', 
(tbl_meter.[turnover]- tbl_meter_backup.[turnover])* tbl_machines.[accounting_denomination] AS 'Turnover', 
(tbl_meter.[total win]- tbl_meter_backup.[total win])* tbl_machines.[accounting_denomination] AS 'Total win', 
(tbl_meter.[games played]-tbl_meter_backup.[games played]) AS 'Games Played', (tbl_meter.[credit in]-tbl_meter_backup.[credit in]) * tbl_machines.[accounting_denomination] AS 'Credit IN', 
(tbl_meter.[Bill in]-tbl_meter_backup.[Bill in])* tbl_machines.[accounting_denomination] AS 'Bill In', 
(tbl_meter.[cancel credit]-tbl_meter_backup.[cancel credit])* tbl_machines.[accounting_denomination] AS 'Cancel Credit', 
tbl_open_backup.[amount] AS 'cgOpen', 
tbl_cancel_backup.[amount] AS 'cgCancel' 
FROM 
tbl_machines 
INNER JOIN tbl_meter ON tbl_machines.[local_no]=tbl_meter.[machine_no] 
Inner join tbl_meter_backup ON tbl_meter_backup.[Machine_No] = tbl_meter.[Machine_No] 
Inner join tbl_open_backup ON tbl_open_backup.[machine_no]=tbl_meter.[machine_no] 
Inner join tbl_cancel_backup on tbl_cancel_backup.[machine_no]=tbl_meter.[machine_no] 
WHERE tbl_meter_backup.[cDate] = @StartDate AND tbl_meter.[cDate] = @EndDate AND tbl_open_backup.[cdate][email protected] AND tbl_cancel_backup.[cdate][email protected]; 

Si tel est le cas, une ou plusieurs de vos tables contiennent plus d'un enregistrement pour les éléments de la jointure. Cela nécessitera une manipulation spéciale, car vous devez déterminer comment savoir quel enregistrement vous voulez.

+0

C'est génial. Ça marche. Merci beaucoup pour votre aide. – Hakan

2

Tout d'abord, il n'y a pas besoin d'inclure toutes les tables du FROM si vous utilisez INNER JOIN.

En second lieu, l'une des suivantes est remplie:

  1. Il y a plusieurs mètres par machine pour le @EndDate donné
  2. Il y a plusieurs meter_backups par machine pour le @StartDate donné
  3. Il y a plusieurs open_backups par machine pour le @EndDate donné
  4. Il y a plusieurs cancel_backups par machine pour la @EndDate donnée

Voir si l'une des lignes suivantes montrent plus de "1" pour le comte:

  1. SELECT count(*), met.[Machine_No], met.[cDate] as EndDate FROM tbl_meter met GROUP BY met.[Machine_No], met.[cDate] ORDER BY count(*) DESC

  2. SELECT count(*), metB.[Machine_No], metB.[cDate] as StartDate FROM tbl_meter_backup metB GROUP BY metB.[Machine_No], metB.[cDate] ORDER BY count(*) DESC

  3. SELECT count(*), openB.[Machine_No], openB.[cDate] as EndDate FROM tbl_open_backup openB GROUP BY openB.[Machine_No], openB.[cDate] ORDER BY count(*) DESC

  4. SELECT count(*), canB.[Machine_No], canB.[cDate] as EndDate FROM tbl_cancel_backup canB GROUP BY canB.[Machine_No], canB.[cDate] ORDER BY count(*) DESC