【问题标题】:MySQLi append more/deeper resultsMySQLi 附加更多/更深的结果
【发布时间】:2016-04-06 15:40:25
【问题描述】:

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

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

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

例如,如果我搜索 ownerX(拥有两间房屋)拥有的房屋,我希望它为 tableB 中的每个相关条目返回两个主要项目和子项目。在下面的示例中,ownerX 有两个房子。 1234 Fake St 上的第一所房子有 2 位不同的房地产经纪人共进行了 3 次访问。 Nowhere St 555 号的第二栋房子有 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;";

同样,实际内容只是假设。我正在寻找更多的“你是个白痴,你应该使用_____”而不是“你拼错了 realtor,这可能是导致问题的原因。”。

另外,请注意,我并不是要求将结果格式化为上面的破折号和括号。我只是简单地这样写,这样更容易理解。我正在寻找一种在 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/relator 示例。

我用他的代码得到了我的结果($house_id 是一个变量输入 id):

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

我得到了一个包含 5 个项目的数组,因为 tableB 有 5 个条目。由于 tableA 中只有 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,如果是新房子,则创建一个新的房子数组项,否则,将tableB中的详细信息添加到当前的房子元素中:

<?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 次访问)。第二个子数组(房屋 2)包含 2 个子数组(对该房屋的 2 次访问)。

我希望这可以帮助任何和我有同样问题的人。如果有人知道更清洁的方法,请在此处发布!谢谢指导! 托尼

【问题讨论】:

  • 查找 LEFT JOIN,应该回答你的问题 :)
  • 请粘贴您当前的代码,以获得上面显示的结果。如果您使用 mysql_multi_query,很可能您正在循环通过 PHP 代码中的结果来生成 JSON,并且需要查看此 PHP 代码以了解如何解决重复 tableA 结果的问题。
  • @ChrisG - 过去一周我一直在努力解决这个问题,我尝试了 LEFT JOIN,但我没有为我工作。我会重新审视它,因为我可能做错了什么。谢谢!
  • @vmachan - 我刚刚用代码更新了我的帖子。谢谢!

标签: php mysql json mysqli


【解决方案1】:

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

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

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

希望这会有所帮助。

【讨论】:

  • 这非常有帮助!我现在要用我所做的来编辑我的帖子。它不是超级干净,但它可以工作。再次感谢!
【解决方案2】:

我没有时间实际编写(和测试!)正确的代码,但我建议您将数据收集到两个 php 关联数组中:$houses 以所有者为键,$visits 以 houseID 为关键。假设所有者可以在市场上拥有多个房产,并且知道房地产经纪人可以对每个房产进行多次访问,那么这两个数组中的条目本身就是“数组数组”。

样本:

$houses={'ownerx':{'houseID_1':['address_1','price_1'],
                   'houseID_2':['address_2','price_2']}},
         'ownery':{'houseID_3':['address_3','price_3'],
                   'houseID_4':['address_4','price_4']}}
        };  
$visits={'houseID_1':['realtorID_1','realtorID_2', ...],
         'houseID_2':['realtorID_3']
        };

// I used JSON notation for simplicity ...

这样做需要您设置一次正确的结构,但这样可以避免您一次又一次地查询相同的数据。从关联数组中检索数据也应该非常有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-20
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    相关资源
    最近更新 更多