Исключение строк из другой таблицы - PullRequest
0 голосов
/ 10 октября 2018

У меня есть приложение, и я пишу функциональность, в которой вы ищете пользователя по различным критериям и расстоянию, однако, если этот пользователь ранее заблокировал вас, вы не сможете увидеть его в результатах.У меня есть 3 таблицы, участвующие в этом запросе: пользователи, почтовые индексы, блоки.Вот то, что я имею до сих пор, к сожалению, это ноль результатов.На самом деле он должен возвращать 101 строку на основе тестовых данных.

Таблица пользователей

> +----------+---------+-----------+
|username  |zipcode  |birthdate  |
+----------+---------+-----------+
|tester55  |72758    |1999-09-09 |
+----------+---------+-----------+
|tester86  |60608    |1983-05-10 |
+----------+---------+-----------+
|iosuser5  |10011    |1975-12-19 |
+----------+---------+-----------+

Blocks table
+----------+---------+-----------+
|blocker   |blockeduser
+----------+---------+-----------+
|tester86  |tester55 |          |
+----------+---------+-----------+
|iosuser5  |tester55 |         |
+----------+---------+-----------+

Zip Code table
+----------+---------+-----------+
|zipcode   |city
+----------+---------+-----------+
|72758     |Rogers   |          |
+----------+---------+-----------+
|60608     |Chicago  |         |
+----------+---------+-----------+
SELECT
zipcodes.zip,
zipcodes.city,
zipcodes.state,
users.*,
YEAR(CURRENT_TIMESTAMP) - YEAR(users.birthdate) -(
    RIGHT(CURRENT_TIMESTAMP, 5) < RIGHT(users.birthdate, 5)
) AS age, blocks.blockeduser, blocks.blocker,
center.seekingdistance,
(
    3959 * ACOS(
        COS(RADIANS(zipcodes.latitude)) * COS(RADIANS(center.latitude)) * COS(
            RADIANS(zipcodes.longitude) - RADIANS(center.longitude)
        ) + SIN(RADIANS(zipcodes.latitude)) * SIN(RADIANS(center.latitude))
    )
) AS distance
FROM
    (
        (
        SELECT
            users.username,
            users.zip,
            users.seekingdistance,
            users.seekingGender AS wantgender,
            users.seekingrace AS wantrace,
            users.seekingmarital AS wantmarital,
            users.seekingminage AS wantminage,
            users.seekingmaxage AS wantmaxage,
            users.seekingminheight AS wantminheight,
            users.seekingmaxheight AS wantmaxheight,
            users.seekingbodytype AS wantbodytype,
            users.seekingreligion AS wantreligion,
            users.seekingeducation AS wanteducation,
            users.seekingoccupation AS wantoccupation,
            users.seekingpolitics AS wantpolitics,
            users.seekingkids AS havekids,
            users.seekingwantkids AS wantwantkids,
            users.seekingdrink AS wantdrinker,
            users.seekingsmoke AS wantsmoker,
            users.gender AS mygender,
            zipcodes.latitude,
            zipcodes.longitude
        FROM
            (
                users
            JOIN zipcodes ON users.zip = zipcodes.zip
            )
        WHERE
            (username = 'tester55')
    ) center,
    zipcodes, blocks
    )
INNER JOIN users ON zipcodes.zip = users.zip
WHERE
    (
        users.username <> 'tester55' AND users.birthdate >= DATE_SUB(
            NOW(), INTERVAL wantmaxage YEAR) AND users.birthdate <= DATE_SUB(
                NOW(), INTERVAL wantminage YEAR) 
            ) AND NOT IN (SELECT blocks.blocker from blocks INNER JOIN users on users.username = blocks.blocker WHERE blocks.blockeduser = "tester55" and blocks.blocker = "tester86")
        HAVING
            (
                distance < center.seekingdistance
            ) 
        ORDER BY
            distance

Буду признателен за любую помощь.Я озадачен тем, как двигаться вперед.

1 Ответ

0 голосов
/ 10 октября 2018

, а ЧЕГО нет в списке?

 AND ?????? NOT IN (
  SELECT blocks.blocker
  FROM blocks
  INNER JOIN users ON users.username = blocks.blocker
  WHERE blocks.blockeduser = "tester55"
   AND blocks.blocker = "tester86"
  )

Я подозреваю, что немедленная проблема заключается в том, что вы не сравниваете что-то, в частности, с "в списке".Поэтому, по большому счету, я предлагаю что-то вроде следующего:

SELECT zipcodes.zip
 , zipcodes.city
 ...
FROM (
 (
  SELECT users.username
   , users.zip
   , users.seekingdistance
   ...
   , zipcodes.latitude
   , zipcodes.longitude
  FROM (
   users INNER JOIN zipcodes ON users.zip = zipcodes.zip
   )
  WHERE (username = 'tester55')
  ) center
 , zipcodes                                          -- is this a cross join ???
 , blocks                                            -- is this another cross join ??
 )
INNER JOIN users ON zipcodes.zip = users.zip
WHERE (
  users.username <> 'tester55'
  AND users.gender = wantgender
  ...
  AND wantminheight <= users.height
  AND wantmaxheight >= users.height
  AND users.birthdate >= DATE_SUB(NOW(), INTERVAL wantmaxage YEAR)
  AND users.birthdate <= DATE_SUB(NOW(), INTERVAL wantminage YEAR)
  )
 AND blocks.blocker NOT IN (                                       -- change here
  SELECT blocks.blocker
  FROM blocks
  INNER JOIN users ON users.username = blocks.blocker
  WHERE blocks.blockeduser = "tester55"
   AND blocks.blocker = "tester86"
  )
HAVING (distance < center.seekingdistance)
ORDER BY distance

Мне действительно не нравятся перекрестные соединения, которые зависят исключительно от запятой - это рецепт для кошмарной отладки.Если имеются предполагаемые перекрестные соединения, используйте «CROSS JOIN»

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