我之前创建了一个查询,用于连接与客户关联的员工。每个客户只分配了2个客户。我的问题是在执行查询之后,对于每个客户,它将所有员工与每个客户相关联,而不是2.这是我到目前为止所拥有的:
SELECT C.customer_ID, C.l_Name AS Surname,
C.f_Name AS 'First Name', C.travel_Date,
T.tour_Name,
GROUP_CONCAT(S.f_Name, S.l_Name ) AS Staff_Concat
FROM Customers AS C
LEFT JOIN Tour AS T ON C.tour_ID = T.tour_ID
LEFT JOIN Staff_Day AS SD ON C.tour_ID = SD.tour_ID
LEFT JOIN Staff_Day AS SD_2 ON SD_2.sd_Date = C.travel_Date
LEFT JOIN Staff AS S ON SD.staff_ID = S.staff_ID
WHERE
C.travel_Date >= '2014-07-08 00:00:00'
AND C.travel_Date <= '2014-07-08 23:59:59'
AND C.customer_ID NOT IN (SELECT O.customer_ID
FROM Customers AS C, Orders AS O
WHERE C.travel_Date >= '2014-07-08 00:00:00'
AND C.travel_Date <= '2014-07-08 23:59:59' AND C.customer_ID = O.customer_ID )
GROUP BY C.customer_ID, Surname, 'First Name', C.travel_Date, T.tour_Name
此查询成功返回正确数量的乘客。但是,它正在为工作人员返回不正确的数据。每位乘客只应分配2名工作人员。此查询似乎返回每个客户的所有员工。我得到的结果是:
6166 customer_Name 2014-07-08 Wildthing Staff1, Staff2, staff3...staff10
预期结果应为:
6166 customer_Name 2014-07-08 Wildthing Staff1, staff2
工作人员,Staff_Day和旅游表的附加图像:
Staff_Day
员工
游览
附件是Customers,Staff,Staff_Day和Tour表的结构:
Table structure for table Customers
Column Type Null Default
customer_ID int(11) No
f_Name varchar(30) Yes NULL
l_Name varchar(30) No
address varchar(100) No
suburb varchar(30) No
state varchar(30) No
country varchar(30) No
postcode varchar(30) No
email varchar(50) No
phone varchar(20) No
child_1 varchar(30) Yes NULL
child_2 varchar(30) Yes NULL
child_3 varchar(30) Yes NULL
child_4 varchar(30) Yes NULL
travel_Date datetime No
signature text No
terms tinyint(1) No
interested_video tinyint(1) Yes 0
specials tinyint(1) Yes NULL
tour_ID int(11) Yes NULL
updated timestamp No CURRENT_TIMESTAMP
Table structure for table Staff
Column Type Null Default
f_Name varchar(30) No
l_Name varchar(30) No
comm_Value int(3) No
staff_Type varchar(50) No
staff_ID int(11) No
bus_ID int(11) No
Table structure for table Staff_Day
Column Type Null Default
sd_ID int(11) No
staff_ID int(4) No
tour_ID int(4) No
sd_Date datetime No
Table structure for table Tour
Column Type Null Default
tour_Name varchar(30) No
tour_ID int(11) No
bus_ID int(11) No
有人告诉我,SQL查询的JOIN部分可能存在问题。任何帮助/指导将不胜感激。如果这是转贴,请道歉。我已经完成了我的研究,但我现在只是碰到了砖墙。
答案 0 :(得分:0)
我认为你的问题就在这一行:
LEFT JOIN Staff_Day AS SD_2 ON SD_2.sd_Date = C.travel_Date
当您似乎只想要具有特定tour_ID的记录时,它会加入您的示例Staff_Day表中的所有记录。如果没有该行的原因,您可以完全删除它。但是,如果您尝试除了tour_ID之外还要按日期过滤Staff_Day表,请尝试将其替换为:
LEFT JOIN Staff_Day AS SD ON C.tour_ID = SD.tour_ID
LEFT JOIN Staff_Day AS SD_2 ON SD_2.sd_Date = C.travel_Date
有了这个:
LEFT JOIN Staff_Day AS SD ON C.tour_ID = SD.tour_ID AND SD.sd_Date = C.travel_Date
这样,您只需加入Staff_Day表一次,就会收到我猜测的结果。
答案 1 :(得分:0)
首先,对您的查询进行非常轻微的重组。您不需要对ID和日期的员工日表进行两次查询,而是按日期创建笛卡尔结果。相反,在BOTH PARTS上使用一个表连接,而不是与员工日表相比硬编码from / to date。你可以做一个DATE_ADD()并且不到一整天...除非你在旅行日期存储时间部分,否则你最好根据日期匹配做,无论时间如何。
所以,第一次左游加入巡演的描述,没问题。 第二个是员工日,然后是基于匹配旅行和日期的工作人员。
最后,你有一个NOT IN(subselect)。我也将其更改为连接格式,但只是为了澄清。它显示您正在尝试获取可能已注册某个特定游览但从未实际放置并提交订单的所有客户的列表。但是......如果有人在同一个客户的不同日期为其他订单注册,他们会有订单存档...但是您将在客户旅行日期强制限定符。在不知道日期和订单表背后的更多细节的情况下......我不确定可能会暴露其他影响。
<强> 修改 强>
由于您仍然遇到笛卡尔结果问题(但没有意义),请将您的联接更改为INNER JOINS,因此巡回赛应该是已知且有效的
SELECT
C.customer_ID,
C.l_Name AS Surname,
C.f_Name AS 'First Name',
C.travel_Date,
T.tour_Name,
GROUP_CONCAT(S.f_Name, S.l_Name ) AS Staff_Concat
FROM
Customers AS C
JOIN Tour AS T
ON C.tour_ID = T.tour_ID
JOIN Staff_Day AS SD
ON C.tour_ID = SD.tour_ID
AND C.Travel_Date >= SD.sd_Date
AND SD.sd_date < Date_add( C.Travel_Date, INTERVAL 1 DAY )
JOIN Staff AS S
ON SD.staff_ID = S.staff_ID
WHERE
C.travel_Date >= '2014-07-08 00:00:00'
AND C.travel_Date <= '2014-07-08 23:59:59'
AND C.customer_ID NOT IN
( SELECT
C.customer_ID
FROM
Customers AS C
JOIN Orders AS O
ON C.customer_ID = O.customer_ID
WHERE
C.travel_Date >= '2014-07-08 00:00:00'
AND C.travel_Date <= '2014-07-08 23:59:59' )
GROUP BY
C.customer_ID,
Surname,
'First Name',
C.travel_Date,
T.tour_Name
关于表格重组的建议。我会更喜欢......
游览 - 一般来说 TourSpecific - 特定的唯一ID,它也具有基于它的游览的ID,但也具有提供的特定时间段。这样,当客户报名参加上午10点到下午2点的旅行时,他们将被分配到SpecificTourID,那么您不必处理时间戳比较。同样,特定日期和时间段的工作人员将具有SpecificTourID,那么您将获得更少的混淆和更简单的查询。
例如:
Tours
TourID TourName
10 Jammin
11 Thriller
12 Thunderstruck
13 Wildthing
SpecificTours
SpecificTourID TourID TourDateTime
1 10 8/1/2014 8:00am
2 10 8/1/2014 1:15pm
3 10 8/4/2014 8:00am
4 10 8/4/2014 1:15pm
Customers
CustomerID FirstName LastName
1 Bill Board
2 Eileen Dover
3 Seymore Hair
Orders
OrderID CustomerID SpecificTourID
1 1 1
2 2 1
3 1 4
StaffDay(类似方法,但使用指定的特定tourID
这样,订单#2的订单适用于特定的旅游1,即旅游10,即Jammin。