多年来我用左连接做了大量的sql查询,但从未见过这个,我找不到任何关于它的信息。
让我们从查询开始
SELECT Services.rn AS srn, Address_Id, Customer_Id, Service_Id, Next_Service, Next_End, Confirmed, Address, First_Name, Last_Name, Company, Service_Type, City
FROM `Services`
LEFT JOIN
(SELECT rn, Address, City_Id FROM `Service_Address`) AS saddresss ON saddresss.rn = Services.Address_Id
LEFT JOIN
(SELECT rn, First_Name, Last_Name, Company FROM `Customer`) AS customer ON customer.rn = Services.Customer_Id
LEFT JOIN
(SELECT rn, Service_Type FROM `Service_Desc`) AS servdesc ON servdesc.rn = Services.Service_Id
LEFT JOIN
(SELECT rn, City FROM `City_List`) AS city ON city.rn = saddresss.City_Id
WHERE `Services`.`Next_Service` BETWEEN " . $daystart . " AND " . $dayend . "
ORDER BY `Services`.`Customer_Id` ASC, `Services`.`Address_Id` ASC, `Services`.`rn` ASC
上面没有包含的是$ daystart和$ dayend变量,它们只是unix时间戳。
通常我会使用while循环来处理结果
while ($row = $res->fetch_assoc())
{
//do something here
}
但是当我得到空输出时,我决定使用var_dump进行调试。如果你var_dump“$ row”你得到一个数组,如果var_dump“$ res-> fetch_assoc()”则相同。但不是这次,如果我var_dump“$ res-> fetch_assoc()”我得到数组,但如果我var_dump“$ row”我得到“bool(true)”为每个“行”。如果尝试回显“$ row”($ row ['City'])中的任何值,我什么也得不到。
显然结果是因为var_dump“$ res-> fetch_assoc()”显示了一个数组并且它有正确的数据,但我不知道我是如何得到的,所以我可以显示它。 / p>
编辑:
我忘了提到我在phpmyadmin中运行查询,只用$ daystart代替1456207200和$ dayend代替1456293599,它就可以了。不知道为什么它不适用于PHP
编辑2:
基于我对DRapp帖子的第二次评论。我想也许“服务”表结构会有所帮助。
CREATE TABLE IF NOT EXISTS `Services` (
`rn` int(10) NOT NULL,
`Customer_Id` int(10) NOT NULL,
`Address_Id` int(10) NOT NULL,
`Service_With` int(10) NOT NULL,
`Service_Id` int(5) NOT NULL,
`Service_Desc` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL,
`Initial_Service` int(10) NOT NULL,
`Last_Service` int(10) NOT NULL,
`Next_Service` int(10) NOT NULL,
`Next_End` int(10) NOT NULL,
`Confirmed` int(1) NOT NULL,
`Product_Quantity` int(5) NOT NULL,
`Product_Rate` double(6,2) NOT NULL,
`Charge` double(6,2) NOT NULL,
`Fequency_Id` int(5) NOT NULL,
`Route` int(5) NOT NULL,
`Salesman` int(5) NOT NULL,
`Warranty_Expires` int(5) NOT NULL,
`Canceled` int(10) NOT NULL DEFAULT '0',
`Cancel_Reason` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL,
`Office_Note` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`Customer_Note` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`Technician_Note` text COLLATE utf8mb4_unicode_520_ci NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=4651 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
答案 0 :(得分:1)
这是一个清理过的SQL查询,没有正确的引号包装,但保留了适合您的参数。 LEFT-JOIN选择对于在查询中添加不必要的图层毫无价值。
我简化了别名引用,希望对你更有意义。为了进行查询,我尝试从FROM子句开始,并确定所有连接以及每个表如何直接相关,以便根据需要获取所有字段。此时,不要担心标准,只是它们如何相关。我也总是尝试将FIRST表列为连接的ON子句的左侧,以及加入TO的ON的右侧。此外,在服务加入服务地址,然后服务地址到城市列表的情况下,请注意我如何缩进...它直接感知什么链接到什么而不是只是被放在任何地方,希望没有人在你之后需要弄清楚事情。当你不得不稍后回到它时也会更容易。
SELECT
S.rn AS srn,
S.Address_Id,
S.Customer_Id,
S.Service_Id,
S.Next_Service,
Next_End,
Confirmed,
SvcAdr.Address,
Cst.First_Name,
Cst.Last_Name,
Cst.Company,
SD.Service_Type,
C.City
FROM
Services AS S
LEFT JOIN Service_Address AS SvcAdr
ON S.Address_Id = SvcAdr.rn
LEFT JOIN City_List AS C
ON SvcAdr.City_Id = city.rn
LEFT JOIN Customer AS Cst
ON Services.Customer_Id = Cst.rn
LEFT JOIN Service_Desc AS SD
ON S.Service_Id = SD.rn
WHERE
S.Next_Service BETWEEN $daystart AND $dayend
ORDER BY
S.Customer_Id ASC,
S.Address_Id ASC,
S.rn ASC
至于它不是通过PHP工作,可能是巧合,但也尝试使用适当的表(或别名)与猜测一起限定你的字段。
服务日期的最后一点,看起来您正在使用基于UNIX的时间戳。我会确保开头是在开始时间的凌晨12:00:00(午夜)和最后一个日期的晚上11:59:59,所以你不会错过任何可能在相应开始的中午/结束日期。
<强>反馈强>
然后我的建议。从ONLY服务查询开始,然后一次添加一个LEFT-JOIN。服务,只需与你的日期范围。如果没有任何东西返回,你知道你的大门。此外,由于您正在进行LEFT-JOIN,因此您可能需要将ex:COALESCE(SvcAdr.Address,&#34;&#34;)应用为地址以防止空值返回。
从
开始SELECT
S.rn AS srn,
S.Address_Id,
S.Customer_Id,
S.Service_Id,
S.Next_Service,
FROM
Services AS S
WHERE
S.Next_Service BETWEEN $daystart AND $dayend
答案 1 :(得分:0)
将我的查询下载到
SELECT *
FROM Services
WHERE Next_Service >= $daystart AND Next_Service <= $dayend
然后主持30分钟,看看是否有任何缺陷,我开始怀疑我的PHP是罪魁祸首。我在OP中提供的while循环是我用于处理查询结果的默认while循环的示例。问题是,在这种情况下,我曾想过快速制作快捷方式以避免额外的“if”语句。我的while循环实际上看起来像
while ($row = $res->fetch_assoc() && $somevalue != '')
{
//do something here
}
而且,如果您对语法一无所知,如果“$ somevalue”不为空,则将“$ row”设置为“bool(true)”。
只是想感谢DRapp的努力,如果可以的话,我会接受你的答案,但因为问题与提供的任何信息无关,我相信它不会随着SO而飞。这是其中的一个哦,我必须承认,我甚至犹豫要发帖,因为它几乎排在那里,如忘记分号(;)等错误。但我希望它可以帮到某人。