繁体   English   中英

SQL 查询连接两个不同的表。 从用户的最后一次交互中查找在线状态

[英]SQL query joining two different tables. Find online status from user's last interaction

问题描述:根据Session表中的最后一次交互查找治疗师用户的在线状态。 不能在User表上保留上次交互日期,但应该在Session表上分开。 但我怎么能加入一个行,并与每一个用户User的表信息和会话数据Session表,每个记录用户最近的互动?

显示治疗师在线状态的问题

图 1 的描述:用户表中的治疗师列表,并根据他们在 Session 表中的最后一次交互显示他们的在线状态

Table1 = **User** email 是这里的主键

图2(User)说明:第一表是user表, email是主键。 它需要与第二列连接,即会话表的StartDate字段作为每条记录的一行。 (粉红色背景的StartDate列不在User表上。 User表列加上粉红色背景的StartDate列是所需的结果)

问题最难的部分是email是连接字段的基础,并且在User表中只有一个,但在Session表中有很多,因为它不是主要的。

表 2 = **会话** 注意电子邮件密钥在每个用户交互时重复

图 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 joinright outer join ,或者full outer join甚至cross join您应该用适当的关键字替换连接原因。 我希望我确实回答了你的问题。

您可以使用MAXSession为派生表中的每封电子邮件查找最新的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM