Php SQL查询在左联接后未返回预期结果(包括架构和pics)
我在前面创建了一个查询,它连接与客户关联的工作人员。每个客户只分配了两个客户。我的问题是在执行查询之后,对于每个客户,它将所有员工与每个客户关联,而不是2个。以下是我到目前为止的情况:Php SQL查询在左联接后未返回预期结果(包括架构和pics),php,mysql,sql,join,left-join,Php,Mysql,Sql,Join,Left Join,我在前面创建了一个查询,它连接与客户关联的工作人员。每个客户只分配了两个客户。我的问题是在执行查询之后,对于每个客户,它将所有员工与每个客户关联,而不是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_Con
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
预期结果应该是:
6166 customer_Name 2014-07-08 Wildthing Staff1, staff2
员工、员工日和旅游表的附图:
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
工作人员日
职员
游览
随附的是客户、员工、员工日和旅游表的结构:
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查询的连接部分可能存在问题。如有任何帮助/指导,将不胜感激。道歉,如果这是一个转载。我已经做了研究,但我现在遇到了困难。我想你的问题在这方面:
LEFT JOIN Staff_Day AS SD_2 ON SD_2.sd_Date = C.travel_Date
这是连接示例Staff_Day表中的所有记录,而您似乎只需要具有特定tour_ID的记录。如果没有理由使用该行,您可以将其完全删除。但是,如果您尝试按日期和巡更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表一次,就会收到我猜是您想要的结果。首先,对您的查询进行非常轻微的重组。您不需要在ID和另一个by date上对staff day表进行两次查询,这会在您身上创建笛卡尔结果。相反,在两个部分上都使用一个表联接,而不是硬编码“从/到日期”与“员工日”表进行比较。你只需添加一个日期,就可以不到一整天。。。除非您在旅行日期上存储时间部分,否则最好基于日期匹配,而不考虑时间 所以,先对左上角加入巡演进行说明,没问题。 第二天是员工日,然后根据匹配的行程和日期安排员工 最后,您有一个NOT IN subselect。我也将其更改为联接格式,但只是为了澄清。似乎您正在尝试获取一份所有客户的列表,这些客户可能已经注册了特定的旅游,但从未实际下过订单。但是如果有人在不同的日期为同一客户注册其他订单,他们将有一个订单存档。。。但是,您将强制在客户旅行日期上使用限定符。如果不知道日期和订单表后面的异常详细信息。。。我不确定可能会受到哪些其他影响 编辑 由于笛卡尔结果仍然存在问题,但没有意义,请将连接更改为内部连接,因此该教程是并且应该是已知和有效的
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
StaffDay采用类似的方法,但使用指定的特定巡回演出
这样,订单2的订单是针对特定的巡演1,即巡演10,即Jammin。谢谢您的回复@DRapp。您是对的,此查询获取的是尚未下订单的客户列表。但是非常感谢修改子选择。我确实试过了,但还是得到了意想不到的结果。虽然我在这一天得到了正确的行数,但对于每个选择了巡演的客户,它显示了所有相关的员工。不管他们是否选择了巡演,工作人员都应该弹出,不管。@AkiraDawson,将查询修改为不使用左联接,而是使用内部联接。客户有一次旅行,最好是一个有效的ID,如果是有效的旅行,我希望您的员工表在给定的一天/旅行中也是有效的。这可能会消除笛卡尔结果的问题。由于您修改了查询,它现在只显示分配给客户巡更的结果。我需要查询来显示客户,无论他们是否被分配了旅游。员工栏仍然列出了所有选择了旅游的指定客户的员工,这仍然让我感到困惑哈哈。我将where子句@DRapp和SD.SD_date>='2014-07-08 00:00:00'和SD.SD_date@AkiraDawson添加到了员工日表中。您展示了样本,但同一天是否有更多不同的员工,例如上午10点、下午12点、下午2点、下午4点的不同人员以及轮班的交替员工?如果是这样的话,这可能就是为什么你在不同的时间有所有的人,并且你在一整天中都有资格加入,而不是该人的旅行计划的具体时间。但是,是的,回到左路。谢谢你的回答。我确实修改了SQL查询,但现在staff列没有出现任何内容。
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