SQL запрос, соединяющий две разные таблицы. Найти онлайн статус из последнего взаимодействия пользователя - PullRequest
0 голосов
/ 16 февраля 2020

Описание проблемы: Поиск онлайн-статуса пользователей терапевта на основе последнего взаимодействия в таблице Session. Невозможно сохранить дату последнего взаимодействия в таблице User, но она должна быть разделена в таблице Session. Но как я могу объединить одну строку для каждого пользователя с User информацией о таблице и данными сеанса из Session таблицы для последнего взаимодействия пользователя с каждой записью?

Problem showing online status of Therapists

Описание рисунка 1: Список терапевтов из таблицы пользователей с отображением их онлайн-статуса на основе их последнего взаимодействия из таблицы сеансов

Table1 = **User** email is the primary key here

Описание figure2 (пользователь): пользователь таблица является первой таблицей, а email является ее первичным ключом. К нему необходимо присоединить второй столбец, то есть поле Session таблицы StartDate в виде одной строки для каждой записи. (Розовый фон StartDate столбца отсутствует в таблице User. User столбцы таблицы плюс розовый фон StartDate столбца - желаемый результат)

Самая сложная часть проблемы - email - основа поля соединения и только одна в таблице User, но содержит много в таблице Session, поскольку она там не является основной.

Table2 = **Session** notice that email key duplicates as per user interacts

Описание figure3 (Session): поле электронной почты дублируется при взаимодействии пользователя с программой. Это своего рода журналы нажатий клавиш, изменяющие личную информацию, например,

Я не могу создать квалифицированный запрос, чтобы решить мою проблему, поэтому я создал запрос для table1 и второй запрос в l oop, который не является правильным способом делать работу. Это вызвало проблемы с производительностью. Мне нужно получить помощь в соединении двух разных запросов одновременно.

Первый запрос фильтрует результаты на основе первичного ключа email из таблицы User . Второй запрос получает последнюю дату сеанса из таблицы Session в l oop.

$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 в обеих таблицах.

Ответы [ 2 ]

1 голос
/ 16 февраля 2020

Вы можете использовать MAX, чтобы найти последние StartDate из Session для каждого сообщения электронной почты в производной таблице и 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
1 голос
/ 16 февраля 2020

Синтаксис 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, вы должны заменить причину объединения на правильные ключевые слова. Я надеюсь, что я ответил на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...