Avatar billede dannv Nybegynder
13. oktober 2005 - 10:12 Der er 13 kommentarer og
1 løsning

Problmer med join

Hejsa,

Jeg skal joine data sammen fra flere forskellige tabeller.. (6 tabeller)

Her kommmer en beskrivelse af tabeller samt den sql jeg har... (medtaget kun relevante kolonner)

tabel: Delivery
-------------------------------------------
delivery_id | order_no | hotel_id | carrier_id |

tabel: delivery_quantity
-------------------------------------------
delivery_id | unit

tabel: order
-------------------------------------------
order_no | customer_id |

tabel: order_quantity
-------------------------------------------
order_no | delivered_qty | ordered_qty | unit

tabel: carrier
-------------------------------------------
carrier_id |

tabel: stockhotel
-------------------------------------------
hotel_id |

tabel: customer
-------------------------------------------
customer_id |


Her er den sql jeg har lavet foreløbig..

-------------------------------------------
SELECT d.delivery_id, d.reg_date, d.remark, d.transfer_pallet_qty, d.transfer_pallet_unit,
q.delivered_qty, q.unit,
o.order_no, o.delivery_date, o.finished,
oq.delivered_qty, oq.ordered_qty, oq.unit,
c.name,
h.name,
cc.name
FROM delivery d,
delivery_quantity q,
order o,
carrier c,
stockhotel h,
customer cc
LEFT JOIN candle_stock.order_quantity oq ON (q.unit = oq.unit)
WHERE d.delivery_id = q.delivery_id
AND d.order_no = o.order_no
AND o.order_no = oq.order_no
AND d.carrier_id = c.carrier_id
AND d.hotel_id = h.hotel_id
AND o.customer_id = cc.customer_id
AND d.delivery_id = 42
ORDER BY q.unit ASC;
-------------------------------------------


Den finder de korrekte informationer, men der i visse situationer mangler der nogle.
Det er specifikt i situationer hvor der i 'delivery_quantity' ikke er et antal
der passer med antallet i 'ordered_quantity'...

Jeg tror der skal insættes nogle LEFT JOIN, jeg har forsøgt men kan ikke få det til at fungerer korrekt..
Avatar billede vallemanden Nybegynder
13. oktober 2005 - 10:17 #1
undskyld men det liner IKKE MySQL men mere MS SQL
Avatar billede fennec Nybegynder
13. oktober 2005 - 10:53 #2
Lad os starte med at lave det om til join syntax. Dette skulle gerne give det samme resultat som den du havde lavet:

SELECT d.delivery_id, d.reg_date, d.remark, d.transfer_pallet_qty, d.transfer_pallet_unit,
q.delivered_qty, q.unit,
o.order_no, o.delivery_date, o.finished,
oq.delivered_qty, oq.ordered_qty, oq.unit,
c.name,
h.name,
cc.name
FROM delivery d
Inner join delivery_quantity q on d.delivery_id = q.delivery_id
Inner Join order o on d.order_no = o.order_no
Inner join carrier c on d.carrier_id = c.carrier_id
Inner join stockhotel h on d.hotel_id = h.hotel_id
Inner join customer cc on o.customer_id = cc.customer_id
LEFT JOIN order_quantity oq ON (q.unit = oq.unit and o.order_no = oq.order_no)
WHERE d.delivery_id = 42
ORDER BY q.unit ASC;

Virker den??
Avatar billede dannv Nybegynder
13. oktober 2005 - 11:01 #3
Det er MySQL ingen tvivl om det.. fennec:

Det virker med en lille tilføjelse af db navn foran order, som jo er et reserveret ord, så denne hente en række men skulle hente 2 (men ja den virker..!

SELECT d.delivery_id, d.reg_date, d.remark, d.transfer_pallet_qty, d.transfer_pallet_unit,
q.delivered_qty, q.unit,
o.order_no, o.delivery_date, o.finished,
oq.delivered_qty, oq.ordered_qty, oq.unit,
c.name,
h.name,
cc.name
FROM delivery d
Inner join delivery_quantity q on d.delivery_id = q.delivery_id
Inner Join candle_stock.order o on d.order_no = o.order_no
Inner join carrier c on d.carrier_id = c.carrier_id
Inner join stockhotel h on d.hotel_id = h.hotel_id
Inner join customer cc on o.customer_id = cc.customer_id
LEFT JOIN order_quantity oq ON (q.unit = oq.unit and o.order_no = oq.order_no)
WHERE d.delivery_id = 42
ORDER BY q.unit ASC;
Avatar billede fennec Nybegynder
13. oktober 2005 - 12:10 #4
Prøv lige at gøre det hele til left join:

SELECT d.delivery_id, d.reg_date, d.remark, d.transfer_pallet_qty, d.transfer_pallet_unit,
q.delivered_qty, q.unit,
o.order_no, o.delivery_date, o.finished,
oq.delivered_qty, oq.ordered_qty, oq.unit,
c.name,
h.name,
cc.name
FROM delivery d
Left join delivery_quantity q on d.delivery_id = q.delivery_id
Left Join ´order´ o on d.order_no = o.order_no
Left join carrier c on d.carrier_id = c.carrier_id
Left join stockhotel h on d.hotel_id = h.hotel_id
Left join customer cc on o.customer_id = cc.customer_id
LEFT JOIN order_quantity oq ON (q.unit = oq.unit and o.order_no = oq.order_no)
WHERE d.delivery_id = 42
ORDER BY q.unit ASC;

Undgå helst reserveret ord, men er de nødvendige kan du "typecaset" dem men ´.
Avatar billede dannv Nybegynder
13. oktober 2005 - 12:26 #5
Nope stadig samme resultat, kun en linie...
Avatar billede fennec Nybegynder
13. oktober 2005 - 12:56 #6
Da det hele er left join, kan der ikke trækkes flere resultater ud, end det du får nu. Det lader til at være et data problem, så kan du smide alle data herind, som der er i hver tabel, eller kan jeg få adgang til databasen??
Avatar billede dannv Nybegynder
13. oktober 2005 - 13:27 #7
Jeg kan smide et dump af de tabeller jeg bruger, der er kun test data i i øjeblikket. Db er ikke offentlig tilgængelig, da den kun ligger her på min lokale pc..
Avatar billede dannv Nybegynder
13. oktober 2005 - 13:29 #8
HER KOMMER DUMP

SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;
SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;
SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;
SET NAMES utf8;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */;


CREATE DATABASE /*!32312 IF NOT EXISTS*/ `candle_stock`;
USE `candle_stock`;
CREATE TABLE `customer` (
  `customer_id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(150) NOT NULL default '',
  `street` varchar(150) default NULL,
  `number` varchar(10) default NULL,
  `zip` varchar(6) default NULL,
  `city` varchar(100) default NULL,
  `telephone_no` varchar(25) default NULL,
  `fax_no` varchar(25) default NULL,
  `email` varchar(100) default NULL,
  `remark` text,
  `reg_date` date default '0001-01-01',
  `contact` varchar(255) default NULL,
  PRIMARY KEY  (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `customer` (`customer_id`,`name`,`street`,`number`,`zip`,`city`,`telephone_no`,`fax_no`,`email`,`remark`,`reg_date`,`contact`) VALUES (1,'Fakta Cincinatti','Fifth Street','35','6500','Cincinatti','+69 00989898','+69 0098765','cincinnati@fakta.dk','Dette er den seneste satsning fra Fakta, nu ogsÃ¥ i the us of a..','2005-09-26','Hr. Dørmand'),(2,'Netto Bornholm','Vejen','43','7878','Rønne','--','--','--','--','2005-09-26','--'),(3,'Bilka Haderslev','Åbakken','12','1212','Haderslvev','--','','','--','2005-10-02','--');
CREATE TABLE `delivery` (
  `delivery_id` int(10) unsigned NOT NULL auto_increment,
  `order_no` int(10) unsigned NOT NULL default '0',
  `hotel_id` int(10) unsigned NOT NULL default '0',
  `carrier_id` int(10) unsigned NOT NULL default '0',
  `delivery_date` date NOT NULL default '0001-01-01',
  `user` varchar(45) default NULL,
  `remark` text,
  `reg_date` date NOT NULL default '0001-01-01',
  `transfer_pallet_qty` int(10) unsigned NOT NULL default '0',
  `transfer_pallet_unit` varchar(55) NOT NULL default '',
  PRIMARY KEY  (`delivery_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `delivery` (`delivery_id`,`order_no`,`hotel_id`,`carrier_id`,`delivery_date`,`user`,`remark`,`reg_date`,`transfer_pallet_qty`,`transfer_pallet_unit`) VALUES (37,1213,2,2,'2005-09-08',NULL,'Her kommer en bemærkning skrevet pÃ¥ en ø...','2005-10-12',4,'Euro Palle'),(38,1213,2,2,'2005-09-08',NULL,'Her kommer endnu en bermærkning skrevet pÃ¥ en Ã¥..','2005-10-12',5,'Euro Palle'),(39,1213,2,2,'2005-09-08',NULL,'','2005-10-12',3,'Euro Palle'),(40,1213,2,2,'2005-09-08',NULL,'','2005-10-12',1,'Euro Palle'),(41,1213,2,1,'2005-09-08',NULL,'','2005-10-12',12,'Euro Palle'),(42,1213,2,2,'2005-09-08',NULL,'','2005-10-12',1,'Euro Palle'),(43,1213,2,2,'2005-09-08',NULL,'','2005-10-12',1,'Euro Palle'),(44,1212,2,2,'2005-09-09',NULL,'','2005-10-12',3,'Euro Palle'),(46,1212,2,2,'2005-09-09',NULL,'Der er her sendt 5 stk kvart paller og 2 stk euro paller','2005-10-13',2,'Euro Palle'),(48,1212,2,1,'2005-09-09',NULL,'Endnu en levering.. 1 kvart palle  (7) 2 plast (4) og 3 engangs','2005-10-13',3,'EngangsPalle');
CREATE TABLE `delivery_quantity` (
  `delivery_id` int(10) unsigned NOT NULL default '0',
  `delivered_qty` int(10) unsigned NOT NULL default '0',
  `unit` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`delivery_id`,`delivered_qty`,`unit`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `delivery_quantity` (`delivery_id`,`delivered_qty`,`unit`) VALUES (37,4,'Kvart Palle'),(37,5,'Kvart Palle Plast'),(38,2,'Kvart Palle'),(38,3,'Kvart Palle Plast'),(39,1,'Kvart Palle'),(39,2,'Kvart Palle Plast'),(40,5,'Kvart Palle'),(41,1,'Kvart Palle'),(41,1,'Kvart Palle Plast'),(42,1,'Kvart Palle'),(43,1,'Kvart Palle'),(43,1,'Kvart Palle Plast'),(44,1,'Kvart Palle'),(44,2,'Kvart Palle Plast'),(46,5,'Kvart Palle'),(48,1,'Kvart Palle'),(48,2,'Kvart Palle Plast');
CREATE TABLE `order` (
  `order_no` int(10) unsigned NOT NULL default '0',
  `customer_id` int(10) unsigned NOT NULL default '0',
  `delivery_date` date NOT NULL default '0001-01-01',
  `finished` tinyint(1) unsigned NOT NULL default '0',
  `reg_date` date NOT NULL default '0001-01-01',
  `remark` text,
  PRIMARY KEY  (`order_no`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `order` (`order_no`,`customer_id`,`delivery_date`,`finished`,`reg_date`,`remark`) VALUES (1212,1,'2005-09-09',0,'2005-09-29',''),(1213,1,'2005-09-08',0,'2005-09-29','--'),(1214,2,'2005-10-01',0,'2005-09-29','Dette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nv'),(1215,2,'2005-10-02',0,'2005-09-29','Dette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.\r\n\r\nDette er en lille bemærkning.\r\nDette er en lille bemærkning.vDette er en lille bemærkning.\r\n\r\nDette er en lille bemærkning.Dette er en lille bemærkning.Dette er en lille bemærkning.'),(1216,1,'2005-12-12',0,'2005-09-29','Endnu en lille bemærkning der kan læses her...'),(1217,2,'2009-12-12',0,'2005-09-29','--'),(4553,1,'2005-10-17',0,'2005-10-02','--');
INSERT INTO `order` (`order_no`,`customer_id`,`delivery_date`,`finished`,`reg_date`,`remark`) VALUES (34567,2,'2005-10-12',0,'2005-10-02','--');
CREATE TABLE `order_quantity` (
  `order_no` int(10) unsigned NOT NULL default '0',
  `delivered_qty` int(10) unsigned NOT NULL default '0',
  `ordered_qty` int(10) unsigned NOT NULL default '0',
  `unit` varchar(50) NOT NULL default '',
  PRIMARY KEY  (`order_no`,`delivered_qty`,`ordered_qty`,`unit`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `order_quantity` (`order_no`,`delivered_qty`,`ordered_qty`,`unit`) VALUES (1212,4,20,'Kvart Palle Plast'),(1212,7,12,'Kvart Palle'),(1213,12,12,'Kvart Palle Plast'),(1213,15,22,'Kvart Palle'),(1214,0,12,'Kvart Palle'),(1214,0,13,'Kvart Palle Plast'),(1214,0,14,'Halv Palle'),(1215,0,11,'Kvart Palle'),(1215,0,12,'Kvart Palle Plast'),(1215,0,13,'Halv Palle'),(1216,0,9,'Halv Palle'),(1216,0,11,'Kvart Palle'),(1216,0,111,'Kvart Palle Plast'),(1217,0,9,'Halv Palle'),(1217,0,10,'Kvart Palle Plast'),(1217,0,11,'Kvart Palle'),(4553,0,350,'Kvart Palle Plast'),(34567,0,7,'Kvart Palle Plast'),(34567,0,10,'Kvart Palle'),(34567,0,90,'Halv Palle');
CREATE TABLE `stockhotel` (
  `hotel_id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  `street` varchar(45) default NULL,
  `number` varchar(45) default NULL,
  `zip` varchar(6) default NULL,
  `city` varchar(45) default NULL,
  `telephone_no` varchar(25) default NULL,
  `fax_no` varchar(25) default NULL,
  `email` varchar(100) default NULL,
  `remark` text,
  `contact` varchar(255) default NULL,
  `reg_date` date default '0001-01-01',
  PRIMARY KEY  (`hotel_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `stockhotel` (`hotel_id`,`name`,`street`,`number`,`zip`,`city`,`telephone_no`,`fax_no`,`email`,`remark`,`contact`,`reg_date`) VALUES (1,'Lagerhotel 1','Hotel vej','90','7878','HotelCity','--','','','--','--','2005-09-27'),(2,'Lagerhotel 0','Gaden','78','--','--','--','','','--','--','2005-09-27'),(3,'Lagerhotel 2','--','--','--','--','--','','','--','--','2005-10-02');
CREATE TABLE `carrier` (
  `carrier_id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(150) NOT NULL default '',
  `street` varchar(100) default NULL,
  `number` varchar(10) default NULL,
  `zip` varchar(6) default NULL,
  `city` varchar(45) default NULL,
  `telephone_no` varchar(25) default NULL,
  `fax_no` varchar(25) default NULL,
  `email` varchar(100) default NULL,
  `remark` text,
  `reg_date` date default '0001-01-01',
  `contact` varchar(255) default NULL,
  PRIMARY KEY  (`carrier_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `carrier` (`carrier_id`,`name`,`street`,`number`,`zip`,`city`,`telephone_no`,`fax_no`,`email`,`remark`,`reg_date`,`contact`) VALUES (1,'Per Andersen','Dernedevej og overfor','29','7899','Dernede ved Dammen','849384989','984594859','per@andersen.dk','Per Andersen Per Andersen Per Andersen \r\n\r\nPer Andersen\r\n\r\nPer Andersen\r\n\r\nPer Andersen\r\n\r\nPer Andersen','2005-09-26','Per Andersen'),(2,'Ove Ovesen','Himmelvej','2','6000','Aabenraa','--','','','--','2005-09-26','--'),(3,'Per Hansen','mmmmm','12','--','--','--','','','--','2005-10-02','--');
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT;
SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS;
SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
Avatar billede fennec Nybegynder
13. oktober 2005 - 14:15 #9
Som jeg kan se det skal der kun komme en række ud.

Ved at vælge kun at se "d.delivery_id = 42" siger dataerne at der kun er en række. Vælger du der imod "o.order_no = 1213" burde du få en lang række.

Hvilke to rækker data ville du da forvente at få ud med "d.delivery_id = 42"???
Avatar billede dannv Nybegynder
13. oktober 2005 - 17:06 #10
delivery_id = 42 benytter ordre_no 1213. Denne ordre har to linier i ordre_quantity tabellen. Der er til delivery_id = 42 leveret en linie i delivery_quantity tabellen. Men mit resultat skal indeholde det som er ordret (til ordre_no 1213) samt det er er leveret på denne ordre.. (delivery_id = 42)

Håber det giver lidt mening...?
Avatar billede fennec Nybegynder
14. oktober 2005 - 08:38 #11
Med "d.delivery_id = 42" kan du naturlig vis ikke trække resultater ud hvor delivery_id ikke er 42.

Du bliver nød til at have et andet kriterie. F.eks "o.order_no = 1213" eller samlet med en OR betingelse:
"(o.order_no = 1213 OR d.delivery_id = 42)"

Er det fordi du kun har værdien 42 at gå ud fra??? For så skal du have fundet ordernr ud fra det, før du kan køre selecten.
Avatar billede dannv Nybegynder
14. oktober 2005 - 09:12 #12
Det er faktisk det jeg gør i øjeblikket, der her jeg 2 selects, først finder jeg info om delivery (inklusive ordre_no) derefter finder jeg ordre data, jeg forsøger bare at begrænse det til en select..

SELECT d.delivery_id, d.reg_date, d.remark, d.transfer_pallet_qty, d.transfer_pallet_unit, d.order_no,
q.delivered_qty, q.unit,
c.name, h.name
FROM delivery d
Inner join delivery_quantity q on d.delivery_id = q.delivery_id
Inner join carrier c on d.carrier_id = c.carrier_id
Inner join "+Attributes.DATABASE+".stockhotel h on d.hotel_id = h.hotel_id
WHERE d.delivery_id = XXX (feks 42..)
ORDER BY q.unit ASC;

Dernæst fra ordre tabellen:
SELECT o.order_no, o.customer_id, o.delivery_date,
o.finished, o.remark, cc.name, oq.delivered_qty,
oq.ordered_qty, oq.unit
FROM order o
LEFT JOIN customer cc ON (o.customer_id = cc.customer_id)
LEFT JOIN candle_stock.order_quantity oq ON (o.order_no = oq.order_no)
WHERE o.order_no = XXX (ordre nummer fra ovenstående query)
ORDER BY oq.unit ASC;
Avatar billede fennec Nybegynder
14. oktober 2005 - 10:52 #13
Hvis det skal være i en select, hvad man godt kan, kræver det som minimum at det er de samme kolonner der bliver valgt i begge selects (og samme rækkefølge). Man kan dog godt snyde den, hvis det ikke er de samme, men det skal være samme datatype.

Det gøres med Union metoden:
select kol1, kol2 from enTabel where id=42
Union
select kol1, kol2 from enTabel where id=43

I dit tilfælde trækker du ikke de samme data ud, også kan du ikke bruge Union.

Hvilke data får du på de 2 selects?? Så kan jeg måske lave en som trækker det samme ud.
Avatar billede dannv Nybegynder
01. februar 2006 - 13:35 #14
lukker kan ikke længere relaterer til dette
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester