php - MySQLi 附加更多/更深的结果

标签 php mysql json mysqli

我很难弄清楚这一点,这可能是因为我没有使用正确的术语。如果有人能给我指出正确的方向,那就太棒了。我将使用一个假设的情况来使事情变得更容易:

我有一个包含两个表的数据库: tableA 包含房屋销售记录(房屋 ID、地址、价格、当前所有者 ID 等) tableB 包含已展示房屋的房地产经纪人的记录(房屋 ID、房地产经纪人 ID、时间和日期、注释等)。

我想要一个查询,可以搜索当前所有者 ID 并下拉他们的所有房屋,其中包含显示该房屋的每个人的信息。我想要检索的是一个 JSON 数组,其中将每个 tableB 记录的信息附加/附加/添加到 tableA 的单个记录中。

例如,如果我搜索ownerX(拥有两栋房屋)拥有的房屋,我希望它返回两个主项目以及tableB中每个相关条目的子项目。在下面的示例中,ownerX 有两栋房子。 1234 Fake St 的第一栋房子有 2 位不同的房地产经纪人总共来访了 3 次。 555 Nowhere St 的第二栋房子有 1 名房地产经纪人来访两次。

以下是我想要检索信息的方式:

tableA - Result 1 (House at address 1234 Fake St)
       tableB - Result 1 (Realtor ID 1234, etc)
       tableB - Result 2 (Realtor ID 1234, etc)
       tableB - Result 3 (Realtor ID 2222, etc)

tableA - Result 2 (House at address 555 Nowhere St)
       tableB - Result 1 (Realtor ID 1111, etc)
       tableB - Result 2 (Realtor ID 1111, etc)

相反,我得到的是:

tableA - Result 1 (House at address 1234 Fake St),tableB(Realtor ID 1234, etc)
tableA - Result 2 (House at address 1234 Fake St),tableB(Realtor ID 1234, etc)
tableA - Result 3 (House at address 1234 Fake St),tableB(Realtor ID 2222, etc)
tableA - Result 4 (House at address 555 Nowhere St),tableB(Realtor ID 2222, etc)
tableA - Result 5 (House at address 555 Nowhere St),tableB(Realtor ID 2222, etc)

我不想每次都检索tableA信息。我只需要一次,然后是 tableB 中的每个子结果。这很重要,因为我将数据返回到创建新列表的应用程序。我目前正在使用 mysqli_multi_query

$sql = "SELECT * FROM tableA WHERE ownerID = "ownerX";";
$sql. = "SELECT tableB.*, tableA.houseID FROM tableB,tableA WHERE tableB.houseID = tableA.houseID;";

再次强调,实际内容只是一个假设。我正在寻找更多的“你是个白痴,你应该使用 _____”,而不是“你拼写错误的房地产经纪人,这可能是导致问题的原因。”。

另外,请注意,我并不要求使用上面的破折号和括号来格式化结果。我只是这样写,这样更容易理解。我正在寻找一种在 JSON 数组中包含子对象的方法。

任何帮助我指明正确方向的帮助将不胜感激!感谢任何花时间尝试这个的人! 托尼

其他信息: 这是我用来运行查询的代码:

$sql = "SELECT * FROM clocks WHERE user_key='".$userkey."';";
$sql .= "SELECT * FROM milestones WHERE (SELECT clock_key FROM clocks WHERE user_key='".$userkey."') = milestones.clock_key";


if (mysqli_multi_query($con,$sql))
{
  do
    {
    if ($result=mysqli_store_result($con)) {
      while ($row=mysqli_fetch_row($result))
        {
          $myArray[] = $row;
        }
        echo json_encode($myArray); 
      mysqli_free_result($result);
      }
    }
while(mysqli_more_results($con) && mysqli_next_result($con));
}

更新答案:

感谢@vmachan 在下面的帖子,我最终一次获得了所有数据,然后通过一些循环来调整数组。我将使用上面的房屋/关系器示例。

我使用他的代码来获取结果($house_id 是一个变量输入 id):

$sql = "SELECT * FROM tableA INNER JOIN tableB ON tableA.houseID = tableB.houseID WHERE tableA.houseID='".$house_id."';";

我得到了一个包含 5 个项目的数组,因为 tableB 有 5 个条目。由于表 A 中只有 2 个房屋条目,因此看起来像这样:

["houseID"=>"1","price"=>"50000", "owner" => "Mike G", "state"=>"CA", "realtor" => "Jane D", "visitDay"=>"Tuesday", "notes" => "They liked the house"],
["houseID"=>"1","price"=>"50000", "owner" => "Mike G", "state"=>"CA", "realtor" => "Jane D", "visitDay"=>"Wednesday", "notes" => "They loved the house"],
["houseID"=>"1","price"=>"50000", "owner" => "Mike G", "state"=>"CA", "realtor" => "Stephanie W", "visitDay"=>"Friday", "notes" => "They didn't like the house"],
["houseID"=>"2","price"=>"65000", "owner" => "Michelle K", "state"=>"AL", "realtor" => "Mark S", "visitDay"=>"Tuesday", "notes" => "They made an offer"],
["houseID"=>"2","price"=>"65000", "owner" => "Michelle K", "state"=>"AL", "realtor" => "Jim L", "visitDay"=>"Monday", "notes" => "They stole stuff"]

前 3 个元素来自 tableA,不会更改。因此,我使用了一个循环来检查 houseID,如果是新房子,则创建一个新的 house 数组项,否则,将 tableB 中的详细信息添加到当前 house 元素中:

<?php
//$house is an array will hold all of our indiviaul houses and their infomation.
$houseArray = array();

//Start the foreach loop 
foreach($items as $item){

//$item["houseID"] is the houseID from our database that we got from the above code.
$houseID =$item["houseID"]; 

//$currentID is a varible that is set after the first iteration.
//This checks to see if we're still working with the same house, or a new house.
if($currentID!=$houseID){

//Create an array to hold all of the relator visit information arrays.
//This is created within the loop as it will erased if a new houseID is found in the array.
$relatorVisitArray = array();

//This is a secondary loop that checks the same array. This time, we are only working with the new houseID that from the condition above.
    foreach($items as $rv){

//This cheecks to see if there is a match between the current houseID that we're working with and the other houseIDs in the array. Since we're going through the same array that we're already iterating, it will find itself (which is good).  
    if($houseID==$rv["houseID"]){

//Once is gets a match, it will create a temporary array to hold the "Relator Visit" information. The array is created within the loop as it needs to be cleared through each iteration.    
    $tempRealitorVisit = array(
        'name' => $rv["name"],
        'day' => $rv["day"],    
        'houseID' => $rv["houseID"],
        'notes' => $rv["notes"]
    );

    //At the end of each iteation, we add the temporary to the main $relatorVisitArray. 
    $relatorVisitArray[] = $tempRealitorVisit;
    }
    }

//At this point, the subloop has ended and we're created an array ($relatorVisitArray) which contains all of the $tempRealitorVisit arrays. 
//Remember, were are still within the first loop and have determined that this is a new house.
//Now we'll create a new house array based on the current houseID in this iteration.
//This array is created within the loop because we want it to cear at the next iteation when it's determined that it's a new house.
    $house = array(
       'houseID' => $item["houseID"],
       'owner' => $item["owner"],
       'price' => $item["price"],
       'location' => $item["location"],
       'relatorVisits' => 
       //Here, we simply add the $relatorVisitArray to a key called, "relatorVisits" (ie an array within an array).
            $relatorVisitArray
       );

//We then add the $house to the $houseArray.      
$houseArray[] = $house;

//Finally, we set $currentID to $item["houseID"]. At the next iteration, it will check this id against the next house ID. If they are the same, this entire code will skip until a new houseID appears from your database. 
$currentID= $item["houseID"];

}

  }

   //This prints all of the information so it's easy to read.
    echo '<pre>';
 print_r($houseArray);
    echo '</pre>';
}

?>

最后,我剩下一个包含两个子数组的数组。第一个子数组(房屋 1)包含 3 个子数组(对该房屋进行 3 次访问)。第二个子数组(House 2)包含 2 个子数组(对该房子进行了 2 次访问)。

我希望这可以帮助任何与我遇到同样问题的人。如果有人知道更干净的方法来做到这一点,请将其发布在这里!感谢您的指导! 托尼

最佳答案

我认为您可以组合如下所示的 SQL 语句来连接 Clock_key 上的时钟和里程碑表,以获得用户提供的值,即 $userkey。然后在您的代码中,您可以循环遍历结果,然后检查连续的 house_ids。

$sql = "SELECT * FROM clocks INNER JOIN milestones ON clocks.clock_key = milestones.clock_key WHERE clocks.user_key='".$userkey."';";

然后您可以使用类似于 SO posting 中的代码。您需要更改它,以便在循环内检查前一个“house_id”是否与当前的相同,如果不同,您将启动一个新的父数组,否则继续添加到现有数组。在循环结束时,您可以调用编码来获取 JSON 格式。

希望这有帮助。

关于php - MySQLi 附加更多/更深的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34567219/

相关文章:

mysql - 我的代码上出现错误消息

MySQL 更新有两个子查询

php - 没有抛出错误,但 PHP 反序列化不成功

php - 在while循环PHP中获取两个相邻的图像

php - 从 php 类调用函数

java - 如何解决具有许多对象和属性的 Json 数组响应?

c# - 如何在 JSON 中为空 DataTable 包含列元数据

java - 无法从 VALUE_STRING token 中反序列化 java.util.ArrayList 的实例

php - 用于删除数据库中选定行的表单 : displays confirmation always

php - CakePHP 中缺少数据库表,我遵循惯例并尝试了所有方法