4

私はこのクエリに完全に夢中になっており、これが単なる子供の遊びである天才がそこにいるのだろうかと思っていました...?

このクエリは、ログインしているユーザーにランダムなユーザーを提案する必要がありますが、ログインしているユーザーと提案されたユーザーの間の関係は、次のいずれかの方法でブロックされてはなりません。

  • 大陸別
  • 国別
  • 年代別
  • 性別による
  • ID別(ブロッカー<->ブロッカー)

テーブル構造

ユーザー

id | username | country_id_home | timestamp_lastonline | gender | birthdate | allow_gender | age_min | age_max | ...

コメント: birthdatemysql-date 形式 ( YYYY-MM-DD)、gender(0=女性、1=男性)、allow_gender(0=両方、1=女性、2=男性)

country_id | name | continent_id | ...

都市

id | city_real | ...

コメント:loc_id_homeテーブル内のuser一致idcities

ブロックされた国

id | user_id | country_id | ...

ブロックされた_大陸

id | user_id | continent_id | ...

ブロックされたユーザー

id | user1_id | user2_id | ...

コメント: user1 は「ブロッカー」、user2 は「ブロッカー」

私が今まで持っているクエリは次のとおりです。

SELECT u.id AS user_id, u.username, u.fname, u.country_id_home, u.timestamp_reg, u.timestamp_upd, u.timestamp_lastonline, u.online_status, u.gender, u.birthdate, u.prof_pic,

(SELECT name FROM countries co WHERE co.country_id=u.country_id_home) AS country_name,
(SELECT city_real FROM cities ci WHERE ci.id=u.loc_id_home) AS city ,
(SELECT region_name FROM regions r WHERE r.id=u.region_id_home) AS region,
(SELECT region_short FROM regions r WHERE r.id=u.region_id_home) AS region_short

FROM user_d1 u 

LEFT JOIN (
SELECT DISTINCT user2_id AS blockee_id
FROM blocked_user
WHERE user1_id = :user1_id1
)this_user_blocked ON u.id = this_user_blocked.blockee_id

LEFT JOIN (
SELECT DISTINCT user1_id AS blocker_id
FROM blocked_user
WHERE user2_id = :user1_id2
)blocked_this_user ON u.id = blocked_this_user.blocker_id

WHERE 

(allow_gender=0 OR allow_gender=:user1_allow_gender)

AND age_min<=:user1_age1
AND age_max>=:user1_age2


AND prof_status<>2

AND this_user_blocked.blockee_id IS NULL AND blocked_this_user.blocker_id IS NULL 

AND NOT EXISTS (SELECT 1 FROM blocked_countries bc WHERE bc.user_id=u.id AND bc.country_id =:user1_country)
AND NOT EXISTS (SELECT 1 FROM blocked_countries bc WHERE bc.user_id=:user1_id3 AND bc.country_id = u.country_id_home)

AND EXISTS (
    SELECT 1 FROM user_d1 u2 
    WHERE u2.id=:user1_id4
    AND (u2.allow_gender=0 OR u2.allow_gender=(u.gender+1))
    AND age_min<=(DATEDIFF(NOW(),u.birthdate))
    AND age_max>=(DATEDIFF(NOW(),u.birthdate))
    AND prof_status<>2
    )

LIMIT 0,6

最後AND EXISTS...のものがなければ結果セットは空ではありませんが、このように常に結果を返しません。まだブロックされた大陸は含まれておらず、まだ注文されていませんtimestamp_lastonline...

最後に何が間違っていAND EXISTS...ますか? それはむしろで行うべきJOINですか?私もそれを試しましたが、空の結果も出ました...

ログインしたユーザーから必要なすべての変数を SESSION-variables に保存しました...より良い方法で実行できるクエリで他に何かが見つかった場合は、私もあなたの助けにとても満足しています!

事前にどうもありがとうございました!

4

1 に答える 1

6

年数ではなく、2 つの日付間の日数DATEDIFFを返す が原因だと思います。したがって、おそらく常に age_max より大きくなります。DATEDIFF

編集:代わりに次のようなことができます:

...
AND DATE_SUB(NOW(), INTERVAL age_max YEAR) <= u.birthdate
AND DATE_SUB(NOW(), INTERVAL age_min YEAR) >= u.birthdate
...
于 2012-07-06T13:06:33.647 に答える