![](/img/trans.png)
[英]I need to update a table joining two different tables. Is this query the appropriate one?
[英]SQL query joining two different tables. Find online status from user's last interaction
问题描述:根据Session
表中的最后一次交互查找治疗师用户的在线状态。 不能在User
表上保留上次交互日期,但应该在Session
表上分开。 但我怎么能加入一个行,并与每一个用户User
的表信息和会话数据Session
表,每个记录用户最近的互动?
图 1 的描述:用户表中的治疗师列表,并根据他们在 Session 表中的最后一次交互显示他们的在线状态
图2(User)说明:第一表是user表, email是主键。 它需要与第二列连接,即会话表的StartDate字段作为每条记录的一行。 (粉红色背景的StartDate
列不在User
表上。 User
表列加上粉红色背景的StartDate
列是所需的结果)
问题最难的部分是email
是连接字段的基础,并且在User
表中只有一个,但在Session
表中有很多,因为它不是主要的。
图 3(会话)的描述:电子邮件字段随着用户在程序中的交互而重复。 它们是更改个人信息的按键日志,例如
我无法创建一个合格的查询来解决我的问题,所以我在循环中为 table1 和第二个查询创建了一个查询,这不是完成这项工作的正确方式。 它导致了性能问题。 我需要帮助同时加入两个不同的查询。
第一个查询根据User表中的主键email
过滤结果。 第二个查询从循环内的会话表中获取最新的会话日期。
$marker_list
是第一个查询, $sql_online
用于嵌套的第二个查询。
<?php
$latitude = filter_input(INPUT_GET, "latitude", FILTER_SANITIZE_SPECIAL_CHARS);
$longitude = filter_input(INPUT_GET, "longitude", FILTER_SANITIZE_SPECIAL_CHARS);
$start = filter_input(INPUT_GET, "start", FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_input(INPUT_GET, "email", FILTER_SANITIZE_EMAIL);
include_once "./connect-db.php";
if ($start == 'undefined') {
$start = 0;
} else {
$start = $start * 10;
}
$distance = 100;
//First query: lists therapists from User table
$marker_list = "SELECT `User`.`uid`, `User`.`latitude`, `User`.`longitude`, `User`.`name`, `User`.`phone_verified`, `User`.`email`, ( 3959 * acos(cos(radians(" . $latitude . ")) * cos(radians(latitude)) * cos(radians(longitude) - radians(" . $longitude . ")) + sin(radians(" . $latitude . ")) * sin(radians(latitude ))) ) AS `distance` FROM `massage`.`User` WHERE rol= 'terapist' AND list_on_maps= '1' AND email_valid='1' HAVING distance < $distance ORDER BY distance LIMIT $start, 7";
if ($results = mysqli_query($conn, $marker_list)) {
$sizeofquery = mysqli_num_rows($results);
$counter = 0;
$maps = array();
while ($row = mysqli_fetch_row($results)) {
$maps[$counter] = new stdClass();
$maps[$counter]->index = $row[0];
$maps[$counter]->latlng = new stdClass();
$maps[$counter]->latlng->latitude = floatval($row[1]);
$maps[$counter]->latlng->longitude = floatval($row[2]);
$maps[$counter]->title = $row[3];
$maps[$counter]->phone_verified = $row[4];
//Second query gets their user interaction from Session table
$sql_online= "SELECT `StartDate` FROM `massage`.`Session` WHERE `email`='$row[5]' ORDER BY `Session`.`StartDate` DESC LIMIT 1";
$result_nested= mysqli_query($conn, $sql_online);
$row_online= mysqli_fetch_array($result_nested);
$delta= (strtotime("now") - strtotime($row_online['StartDate']));
if ($delta < 300 ) {
$maps[$counter]->online = "y";
} else if ( $delta < 600){
$maps[$counter]->online = "t";
} else {
$maps[$counter]->online = "g";
}
$counter++;
}
$maps->counter = $row['counter'];
$mapsJSON = json_encode($maps);
}
//Third Query: Inserts last interaction as listing therapists as on many pages. It is not an important part of the question.
$sql_session = "INSERT INTO `massage`.`Session` (`StartDate`, `email`, `Interaction`) VALUES (current_timestamp(), '$email', 'dolistmaps');";
mysqli_query($conn, $sql_session);
header('Content-type:application/json;charset=utf-8');
echo $mapsJSON;
mysqli_free_result($results);
mysqli_close($conn);
所以请帮助我创建一个查询,它完成在两个表的公共字段email
上连接两个不同的表。
连接两个表的SQL
语法使用JOIN
关键字。 可以使用以下语法连接具有公共列的两个表:
select StartDate
from Masage.Session masag
inner join User user on masag.email = user.email
这是用于inner join
。 如果您想要left outer join
或right outer join
,或者full outer join
甚至cross join
您应该用适当的关键字替换连接原因。 我希望我确实回答了你的问题。
您可以使用MAX
从Session
为派生表中的每封电子邮件查找最新的StartDate
并将其JOIN
到用户表中以获得您需要的结果:
SELECT `User`.`uid`,
`User`.`latitude`,
`User`.`longitude`,
`User`.`name`,
`User`.`phone_verified`,
`User`.`email`,
( 3959 * acos(cos(radians(" . $latitude . ")) * cos(radians(latitude)) * cos(radians(longitude) - radians(" . $longitude . ")) + sin(radians(" . $latitude . ")) * sin(radians(latitude ))) ) AS `distance`,
s.StartDate
FROM `massage`.`User`
JOIN (
SELECT email, MAX(StartDate) AS StartDate
FROM `massage.Session`
GROUP BY email
) s ON s.email = `User`.email
WHERE rol= 'terapist' AND list_on_maps= '1' AND email_valid='1'
HAVING distance < $distance
ORDER BY distance
LIMIT $start, 7
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.