Php 基于另一个数组从数组中删除行

Php 基于另一个数组从数组中删除行,php,mysql,sql,Php,Mysql,Sql,我完全被难倒了,并且尝试了我找到的不同的解决方案,但是没有任何效果。我的问题是: 我有两张结构完全不同的桌子。一个表用于用户,另一个表用于块。目标是从用户搜索中删除块表中显示的所有项 我曾尝试通过使用NOT IN的SQL查询来实现这一点,但它只排除了其中一项 我也尝试过PHP中的array_diff,但我仍然在用户搜索结果中看到被阻止的用户 我不知道表结构是否必须匹配,或者我的SQL是否太复杂。有什么指导吗 表结构 > +----------+---------+-----------+

我完全被难倒了,并且尝试了我找到的不同的解决方案,但是没有任何效果。我的问题是:

我有两张结构完全不同的桌子。一个表用于用户,另一个表用于块。目标是从用户搜索中删除块表中显示的所有项

我曾尝试通过使用NOT IN的SQL查询来实现这一点,但它只排除了其中一项

我也尝试过PHP中的array_diff,但我仍然在用户搜索结果中看到被阻止的用户

我不知道表结构是否必须匹配,或者我的SQL是否太复杂。有什么指导吗

表结构

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


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

Zip Code table
+----------+---------+-----------+
|zipcode   |city
+----------+---------+-----------+
|72758     |Rogers   |          |
+----------+---------+-----------+
|60608     |Chicago  |         |
+----------+---------+-----------+
编辑:根据@TomC的反馈更新查询

    SELECT
    *
FROM
    (
    SELECT
        zipcodes.zip,
        zipcodes.city,
        zipcodes.state,
        users.id,
        users.username,
        users.ava,
        users.gender,
        users.race,
        users.headline,
        users.marital,
        users.height,
        users.bodytype,
        users.religion,
        users.education,
        users.occupation,
        users.politics,
        users.kids,
        users.wantkids,
        users.favdrink,
        users.drink,
        users.smoke,
        users.interests,
        users.aboutme,
        users.seekingGender,
        users.seekingdistance,
        users.seekingrace,
        users.seekingmarital,
        users.seekingminage,
        users.seekingmaxage,
        users.seekingminheight,
        users.seekingmaxheight,
        users.seekingbodytype,
        users.seekingreligion,
        users.seekingeducation,
        users.seekingoccupation,
        users.seekingpolitics,
        users.seekingkids,
        users.seekingwantkids,
        users.seekingdrink,
        users.seekingsmoke,
        users.birthdate,
        YEAR(CURRENT_TIMESTAMP) - YEAR(users.birthdate) -(
            RIGHT(CURRENT_TIMESTAMP, 5) < RIGHT(users.birthdate, 5)
        ) AS age,
        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
        users AS seeker
    JOIN zipcodes AS center
    ON
        center.zip = seeker.zip
    JOIN users ON seeker.zip = users.zip
    JOIN zipcodes ON zipcodes.zip = users.zip
    WHERE
        seeker.username = 'tester55' AND seeker.username <> users.username AND users.gender = seeker.seekingGender AND seeker.gender = users.seekingGender AND users.seekingmarital LIKE seeker.seekingmarital AND users.bodytype LIKE seeker.seekingbodytype AND users.religion LIKE seeker.seekingreligion AND users.education LIKE seeker.seekingeducation AND users.occupation LIKE seeker.seekingoccupation AND users.politics LIKE seeker.seekingpolitics AND users.kids LIKE seeker.seekingkids AND users.wantkids LIKE seeker.seekingwantkids AND users.drink LIKE seeker.seekingdrink AND users.smoke LIKE seeker.seekingsmoke AND users.race LIKE seeker.seekingrace AND seeker.seekingminheight <= users.height AND seeker.seekingmaxheight >= users.height AND users.birthdate >= DATE_SUB(
            NOW(), INTERVAL seeker.seekingmaxage YEAR) AND users.birthdate <= DATE_SUB(
                NOW(), INTERVAL seeker.seekingminage YEAR) AND NOT EXISTS(
                SELECT
                    *
                FROM
                    blocks
                WHERE
                    where blocks.blockeduser=seeker.username and blocks.blocker=users.username
            )
            ) selections
        WHERE
            distance < selections.seekingdistance
        ORDER BY
            distance

假定此结构是正确的:

MariaDB [test]> SELECT * FROM `Users`;
+----------+---------+------------+
| username | zipcode | birthdate  |
+----------+---------+------------+
| tester55 |   72758 | 1999-09-09 |
| tester86 |   60608 | 1983-05-10 |
| iosuser1 |   10011 | 1975-12-19 |
| iosuser5 |   10011 | 1975-12-21 |
+----------+---------+------------+
4 rows in set (0.00 sec)

您可以使用以下查询:

MariaDB [test]> SELECT `Users`.* FROM `Users` LEFT JOIN `Blocks` ON `Users`.`username` = `Blocks`.`blocker` WHERE `Blocks`.`blocker` IS NULL;
+----------+---------+------------+
| username | zipcode | birthdate  |
+----------+---------+------------+
| tester55 |   72758 | 1999-09-09 |
| iosuser1 |   10011 | 1975-12-19 |
+----------+---------+------------+
2 rows in set (0.00 sec)

没有必要声明表具有完全不同的结构,这就是数据库的全部概念。您可以按照@EmaniAzevedo的建议使用左连接,但需要根据需要检查这两个列,或者使用not exists

我宁愿不存在,因为我认为它更清晰

select * from users 
where not exists(
    select * from blocks where Users.username = Blocks.blocker or users.username=Blocks.blockeduser
)
编辑:正如您现在添加的查询一样,此not exists应该作为附加子句,使用AND添加该子句。我也不明白你为什么要用have,我想那也应该是AND

第二次编辑:这是删除了混淆括号的整个查询。它现在从查找用户开始,在同一个zip中查找所有其他用户,然后查找所有其他匹配用户。可以对别名用户表执行此操作,而不必使用嵌套查询

顺便说一句,它检查用户是否在阻止程序表的任一侧-如果不正确,则相应地修改

select * from (
SELECT  zipcodes.zip, zipcodes.city, zipcodes.state,
        users.id, users.username, users.ava, users.gender, users.race, users.headline, users.marital, users.height, users.bodytype, users.religion, users.education, 
        users.occupation, users.politics, users.kids, users.wantkids, users.favdrink, users.drink, users.smoke, users.interests, users.aboutme, users.seekingGender, 
        users.seekingdistance, users.seekingrace, users.seekingmarital, users.seekingminage, users.seekingmaxage, users.seekingminheight, users.seekingmaxheight, 
        users.seekingbodytype, users.seekingreligion, users.seekingeducation, users.seekingoccupation, users.seekingpolitics, users.seekingkids, users.seekingwantkids, 
        users.seekingdrink, users.seekingsmoke, users.birthdate, 
        YEAR(CURRENT_TIMESTAMP) - YEAR(users.birthdate) - (RIGHT(CURRENT_TIMESTAMP, 5) < RIGHT(users.birthdate, 5)) as age, 
        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 users as seeker
join zipcodes as centre on centre.zip=seeker.zip
JOIN users ON seeker.zip = users.zip
join zipcodes on zipcodes.zip=users.zip
where seeker.username = 'tester55' and seeker.username<>users.username AND users.gender = seeker.seekingGender AND seeker.gender=users.seekingGender
    AND users.seekingmarital LIKE seeker.seekingmarital AND users.bodytype LIKE seeker.seekingbodytype AND users.religion LIKE seeker.seekingreligion 
    AND users.education LIKE seeker.seekingducation and users.occupation LIKE seeker.seekingoccupation AND users.politics LIKE seeker.seekingpolitics 
    AND users.kids LIKE seeker.seekingkids AND users.wantkids LIKE seeker.seekingwantkids AND users.drink LIKE seeker.seekingdrinker 
    AND users.smoke LIKE seeker.seekingsmoker AND users.race LIKE seeker.seekingrace AND seeker.seekingminheight <= users.height AND seeker.seekingmaxheight >= users.height 
    AND users.birthdate >= DATE_SUB(NOW(), INTERVAL seeker.seekingmaxage YEAR) AND users.birthdate <= DATE_SUB(NOW(), INTERVAL seeker.seekingminage YEAR)
    and not exists(
        select * from blocks where blocks.blocker=users.username and blocks.blockeduser=seeker.username
    )
) selections
where distance < selections.seekingdistance
ORDER BY distance

应该返回什么?您的用户表叫什么?用户表叫用户。根据数据集,应返回IOSUER1。如果我发布我的查询,会有帮助吗。这是一个基于用户偏好和距离进行搜索的冗长查询。它将执行搜索的用户从结果中排除,并检查他们是否被任何人阻止。看起来它应该只删除其中一个项目。表上的blocker和blockeduser是否颠倒?@msg根据示例,它应该返回IOSUER1。Blocker和blockeduser没有颠倒。嗨@Ernani,我试图将您的解决方案合并到我的查询中。但是我有错误。当我单独尝试你的问题时,效果很好。如果我发布完整的查询,会有帮助吗。我真的很感谢你的帮助。我已经在我的问题中添加了。它很长而且不是最好的,所以请对我放松点。
select * from (
SELECT  zipcodes.zip, zipcodes.city, zipcodes.state,
        users.id, users.username, users.ava, users.gender, users.race, users.headline, users.marital, users.height, users.bodytype, users.religion, users.education, 
        users.occupation, users.politics, users.kids, users.wantkids, users.favdrink, users.drink, users.smoke, users.interests, users.aboutme, users.seekingGender, 
        users.seekingdistance, users.seekingrace, users.seekingmarital, users.seekingminage, users.seekingmaxage, users.seekingminheight, users.seekingmaxheight, 
        users.seekingbodytype, users.seekingreligion, users.seekingeducation, users.seekingoccupation, users.seekingpolitics, users.seekingkids, users.seekingwantkids, 
        users.seekingdrink, users.seekingsmoke, users.birthdate, 
        YEAR(CURRENT_TIMESTAMP) - YEAR(users.birthdate) - (RIGHT(CURRENT_TIMESTAMP, 5) < RIGHT(users.birthdate, 5)) as age, 
        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 users as seeker
join zipcodes as centre on centre.zip=seeker.zip
JOIN users ON seeker.zip = users.zip
join zipcodes on zipcodes.zip=users.zip
where seeker.username = 'tester55' and seeker.username<>users.username AND users.gender = seeker.seekingGender AND seeker.gender=users.seekingGender
    AND users.seekingmarital LIKE seeker.seekingmarital AND users.bodytype LIKE seeker.seekingbodytype AND users.religion LIKE seeker.seekingreligion 
    AND users.education LIKE seeker.seekingducation and users.occupation LIKE seeker.seekingoccupation AND users.politics LIKE seeker.seekingpolitics 
    AND users.kids LIKE seeker.seekingkids AND users.wantkids LIKE seeker.seekingwantkids AND users.drink LIKE seeker.seekingdrinker 
    AND users.smoke LIKE seeker.seekingsmoker AND users.race LIKE seeker.seekingrace AND seeker.seekingminheight <= users.height AND seeker.seekingmaxheight >= users.height 
    AND users.birthdate >= DATE_SUB(NOW(), INTERVAL seeker.seekingmaxage YEAR) AND users.birthdate <= DATE_SUB(NOW(), INTERVAL seeker.seekingminage YEAR)
    and not exists(
        select * from blocks where blocks.blocker=users.username and blocks.blockeduser=seeker.username
    )
) selections
where distance < selections.seekingdistance
ORDER BY distance
create table users (username varchar(20),zipcode varchar(10),birthdate date)
insert users values ('tester55','10011','1999-09-09')
,('tester86','10011','1983-05-10')
,('iosuser1','10011','1975-12-19')
,('iosuser5','10011','1975-12-21')
,('tester150','10011','1975-12-21')

create table Blocks(blocker varchar(20),blockeduser varchar(20))
insert Blocks values ('tester86','tester55'),('iosuser5','tester55'),('tester150','tester55')

create table ZipCode(zipcode varchar(10), city varchar(20))
insert zipcode values ('72758','Rogers'),('60608','Chicago')

select users.*
from users seeker
join users on users.zipcode=seeker.zipcode and users.username<>seeker.username
where seeker.username='tester55'
and not exists(select * from blocks where blocks.blocker=users.username and blocks.blockeduser=seeker.username)
username    zipcode birthdate
iosuser1    10011   1975-12-19