mysql查询$ row返回“bool(true)”而不是结果数组

时间:2016-02-24 02:13:10

标签: php mysql

多年来我用左连接做了大量的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;

2 个答案:

答案 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而飞。这是其中的一个哦,我必须承认,我甚至犹豫要发帖,因为它几乎排在那里,如忘记分号(;)等错误。但我希望它可以帮到某人。