从另一个表中排除行

时间:2018-10-10 03:50:40

标签: mysql sql

我有一个应用程序,正在编写功能,您可以在其中基于不同的条件和距离搜索用户,但是如果该用户先前已阻止了您,则您将无法在结果中看到他们。我有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 :(得分:0)

什么不在里面?

 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”