我已使用以下命令创建表格。
CREATE TABLE Customer(
custid int NOT NULL AUTO_INCREMENT,
fname varchar(30) NOT NULL,
lname varchar(30) NOT NULL,
mno varchar(10),
password varchar(30),
PRIMARY KEY (custid)
);
CREATE TABLE Employee(
empid int NOT NULL,
fname varchar(30) NOT NULL,
lname varchar(30) NOT NULL,
mno varchar(10),
password varchar(30),
PRIMARY KEY (empid)
);
CREATE TABLE Address(
id int NOT NULL,
street varchar(30),
doorno varchar(30),
city varchar(30),
statee varchar(30),
zip varchar(5),
county varchar(30) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES Customer (custid)
);
CREATE TABLE EmpAddress(
id int NOT NULL,
street varchar(30),
doorno varchar(30),
city varchar(30),
statee varchar(30),
zip varchar(5),
county varchar(30) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (id) REFERENCES Employee (empid)
);
CREATE TABLE Service(
serviceid int NOT NULL,
serviceType varchar(30),
amount int,
PRIMARY KEY (serviceid)
);
CREATE TABLE Booking(
bookingid int NOT NULL AUTO_INCREMENT,
empid int NOT NULL,
custid int NOT NULL,
serviceid int NOT NULL,
PRIMARY KEY (bookingid),
FOREIGN KEY (empid) REFERENCES Employee (empid),
FOREIGN KEY (custid) REFERENCES Customer (custid),
FOREIGN KEY (serviceid) REFERENCES Service (serviceid)
);
CREATE TABLE Availability(
empid int NOT NULL,
datee date NOT NULL,
startTime int NOT NULL,
PRIMARY KEY (empid, datee, startTime),
FOREIGN KEY (empid) REFERENCES Employee (empid)
);
CREATE TABLE Transactions(
bookingid int NOT NULL,
paymentMethod varchar(20),
serviceid int,
amount int,
PRIMARY KEY (bookingid),
FOREIGN KEY (bookingid) REFERENCES Booking (bookingid),
FOREIGN KEY (serviceid) REFERENCES Service (serviceid)
);
我正在尝试编写一个返回bookingid,firstName,lastName,street,door no,邮政编码,serviceType,date和startTime GIVEN empid的查询。
它基本上是5个表的连接,我将查询实现为:
SELECT B.bookingid, C.fname, C.lname, AD.street,
AD.doorno, AD.zip,S.serviceType, A.datee, A.startTime
FROM booking as B, availability as A, customer as C,
address as AD, Service as S
WHERE
B.empid=501 AND B.custid=C.custid
AND C.custid=AD.id
AND B.serviceid=S.serviceid AND B.empid=A.empid;
所需的结果应该是:
BookingID fname lname street doorno zipcode serviceType date starttime
1 X Y ABC 33 5335 Clean 2015-05-20 9
2 P Q NMO 55 8294 Shift 2015-06-11 11
但结果给了我表的交叉产品:
BookingID fname lname street doorno zipcode serviceType date starttime
1 X Y ABC 33 5335 Clean 2015-05-20 9
1 X Y ABC 33 5335 Shift 2015-06-11 11
2 P Q NMO 55 8294 Clean 2015-05-20 9
2 P Q NMO 55 8294 Shift 2015-06-11 11
请让我知道我的查询有什么问题。
答案 0 :(得分:1)
可用性的主键目前是(empid, datee, startTime)
,但JOIN仅在Booking.empid
上完成 - 每个Employee可能有多个可用性行。
我相信您需要在Booking
添加时间戳,并在加入期间插入日期Availability
:
CREATE TABLE Booking(
-- ...
bookingDate datetime NOT NULL,
-- ...
);
我还建议您添加和结束日期时间范围到可用性,并将日期和时间存储为一个(否则您将需要不断添加时间):
CREATE TABLE Availability(
-- ...
startDateTime datetime NOT NULL,
endDateTime datetime NOT NULL,
PRIMARY KEY (empid, startDateTime), -- Put some rules to prevent overlap
);
然后查询将日期和时间的预订插入到可用性中:
SELECT B.bookingid, C.fname, C.lname, AD.street, AD.doorno, AD.zip,
S.serviceType, A.startDateTime
FROM
booking as B
INNER JOIN customer as C
ON B.custid=C.custid
INNER JOIN availability as A
ON B.empid=A.empid AND b.bookingDate BETWEEN A.startDateTime AND A.endDateTime
INNER JOIN address as AD
ON C.custid=AD.id
INNER JOIN Service as S
ON B.serviceid=S.serviceid
WHERE
B.empid=501;
我还调整了联接以使用JOIN ON
而不是WHERE
中的联接。
这将解决重复的可用性数据。但是,我无法看到ServiceType
对于同一预订会有什么不同。
答案 1 :(得分:0)
您可以使用DISTINCT
来消除重复记录。也总是尝试使用显式连接。
SELECT DISTINCT B.bookingid, C.fname, C.lname, AD.street,
AD.doorno, AD.zip,S.serviceType, A.datee, A.startTime
FROM booking as B
INNER JOIN availability as A ON B.empid = A.empid
INNER JOIN customer as C ON B.custid = C.custid
INNER JOIN address as AD ON C.custid = AD.id
INNER JOIN Service as S ON B.serviceid = S.serviceid
WHERE B.empid = 501