MySQL запрос не показывает результаты должным образом - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть 2 таблицы. Одна из моих таблиц с users:

id         name     longitude       latitutde  
-----      -----    -----------    -----------
1          Mark     -82.347036     29.6545095
2          John     -82.357036     29.665095
3          Paul     -82.367036     29.645095
4          Dave     -82.337036     29.675095
5          Chris    -82.437036     29.575095
6          Manny    -82.538036     29.745095
7          Fred     -82.638036     29.346095

Я использую SQL, чтобы обнаружить близлежащих людей:

 SELECT id, 
        ( 3959 * acos( cos( radians(37) ) * cos( radians( latitude ) ) *
             cos( radians( longitude ) - radians(-122) ) +
              sin( radians(37) ) * sin(radians(latitude)) ) 
             ) AS distance
    FROM `users` HAVING distance < 50 ORDER BY distance DESC LIMIT 20`

Другая matches выглядит следующим образом:

id         sender    receiver        status  
-----      -----    -----------    -----------
1            3           4              0
2            1           5              1
3            6           3              1
4            2           6              0
5            2           1              0

Где отправитель - лицо, отправившее приглашение, - получатель приглашения.

Мой запрос:

SELECT
a.id
,a.distance
FROM
  (Select  
       id,
       st_distance_sphere(POINT(-82.337036, 29.645095 ),
                          POINT(`longitude`, `latitude` ))/1000  as distance
    FROM
        users u  
    WHERE id <> 1 
    HAVING distance < 5000 
    ORDER BY distance 
    DESC LIMIT 20) a
WHERE
    a.id in (SELECT `sender` FROM matches WHERE status = 1)
    OR a.id NOT IN ( SELECT `sender` FROM matches
           UNION ALL SELECT `receiver` FROM matches )
ORDEr BY a.distance ASC

Моя скрипка: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=95972531a390a013796ed4cf7ad99884

В таблице совпадений Id 1 имеют совпадения только с Id 5 (где статус 1).

Часть с:

       a.id     in ( SELECT `sender` FROM matches WHERE status = 1)
    OR a.id NOT IN ( SELECT `sender` FROM matches
           UNION ALL SELECT `receiver` FROM matches )

неверна где-то, потому что он должен показать id 2,3,4,6,7 не только 6 & 7. Проверьте последний запрос в скрипте

Запрос должен быть с logi c:

Если я sender с идентификатором 1, не возвращайте мне receiver (a.id ).

Если я receiver с идентификатором 1, верните мне sender (a.id), где status = 0.

Если я не sender или receiver верните мне a.id

Ответы [ 2 ]

2 голосов
/ 30 апреля 2020

Когда я использую вашу логику c

Вы хотите:

SELECT 
    a.id, a.distance
FROM
    (SELECT 
        id,
            ST_DISTANCE_SPHERE(POINT(- 82.337036, 29.645095), POINT(`longitude`, `latitude`)) / 1000 AS distance
    FROM
        users u
    WHERE
        id <> 1
    HAVING distance < 5000
    ORDER BY distance DESC
    LIMIT 20) a
WHERE
    a.id NOT IN (SELECT `sender` FROM (SELECT `sender` FROM matches UNION  SELECT `receiver` FROM matches) t1
WHERE `sender` IN (SELECT `sender` FROM matches WHERE `receiver` = 1 AND status = 1
UNION SELECT `receiver` FROM matches WHERE `sender`  = 1
))
ORDER BY a.distance ASC
id |           distance
:- | -----------------:
3  | 2.8991986256467865
2  |  2.946298180421104
4  |  3.335840468953696
7  |  44.20441197234838

db <> скрипка здесь

1 голос
/ 01 мая 2020
   a.id     in ( SELECT `sender` FROM matches WHERE status = 1)
OR a.id NOT IN ( SELECT `sender` FROM matches
       UNION ALL SELECT `receiver` FROM matches )

Первая часть ИЛИ получает идентификаторы отправителей, следовательно, идентификаторы 1 и 6.

Но вторая часть еще более инкриминирует.

SELECT `sender` FROM matches    -- 1,2,2,3,    6
UNION ALL 
SELECT `receiver` FROM matches  -- 1,    3,4,5,6

UNION ALL равно 1,1,2,2,3,3,4,5,6,6.

Пары игнорируются.

Между тем, a.id является некоторым подмножеством 1,2,3,4,5,6,7, в зависимости от арифметического расстояния c. Следовательно, единственный a.id, оставшийся от второй части OR, - это 7.

Итак, я ожидаю получить 1, 6 и, возможно, 7.

Хммм. .. Я думаю, что я заблудился, и я думаю, что вы заблудились. Пожалуйста, измените вещи так, чтобы не было двух ids, а 4 значений 1. 1 как status, 1 как отправитель / получатель, 1 как два разных ids. Например, сделайте match.id между 11 и 16; сделать все отправители / получатели между 21 и 27. Сделать статусы ON и OFF (или что-то).

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