简体   繁体   English

PHP / MySQL-需要协助,编写SQL查询

[英]PHP/MySQL - Need assistance writing a SQL Query

I have a martial arts website where I have users in one table and the belts they have earned in another. 我有一个武术网站,在一张桌子上有用户,而在另一张桌子上有用户。 Here are some example tables / data to help describe my problem: 以下是一些示例表/数据来帮助描述我的问题:

Users table : Users表:

+---------------------+
| Users               |
+---------------------+
| userid | name       |
+---------------------+
|    1   | Fred Smith |
+---------------------+

Belts table : Belts表:

+------------------------------------------+
| id | userid | belt_colour | awarded_date |
+------------------------------------------+
| 1  |    1   |   blue      |  2007-01-01  |
+------------------------------------------+
| 2  |    1   |   purple    |  2008-01-01  |
+------------------------------------------+
| 2  |    1   |   brown     |  2009-01-01  |
+------------------------------------------+

My problem is this: When you click brown, to view all brown belts I want you to see Fred. 我的问题是:当您单击棕色时,要查看所有棕色皮带,我希望您看到弗雷德。 I DO NOT want Fred to appear in lists of blue and purple belts (which is what is happening at the moment). 我不希望Fred出现在蓝色和紫色皮带的列表中(此刻正在发生这种情况)。

I am struggling to come up with a query that goes something like this: 我正在努力提出这样的查询:

show me all users where belt=$belt but only if they do not have an entry for a higher belt. 向我显示所有用户,其中belt = $ belt,但前提是他们没有更高皮带的条目。

Another example: I am purple but I show up in blue list because details of my blue belt are in the belts table too :-( 另一个例子:我是紫色的,但我出现在蓝色列表中,因为我的蓝色皮带的详细信息也在皮带表中:-(

Any assistance greatly appreciated! 任何协助,不胜感激!

Assuming a higher belt means a higher awarded_date, one option is to get the MAX of awarded_date for each user and join back to the belt table: 假设更高的皮带意味着更高的dashed_date,一个选择是获取每个用户的maxed_date MAX并重新加入皮带表:

SELECT u.userId, u.name
FROM Users u
    JOIN (
        SELECT userId, MAX(awarded_date) max_awarded_date
        FROM Belts
        GROUP BY userId
   ) maxb ON u.userId = maxb.userId
   JOIN Belts b ON b.userId = maxb.userId 
       AND b.awarded_date = maxb.max_awarded_date
WHERE b.belt_colour = 'brown'

Sort by _awarded_date_ descending. 按_awarded_date_降序排序。 And limit 1 to the result. 并将结果限制为1

Since every Belt is awarded one after the other, the most recent, is the one that you want to show. 因为每个腰带都被一个接一个地授予,所以您要展示最近的那个。 So, your query would be like this: 因此,您的查询将如下所示:

 select * from Users u, Belts b where u.userid = b.userid order by awarded_date limit 1;

Hope this helps. 希望这可以帮助。

Let's split this problem in two: 让我们将这个问题一分为二:

  1. First, you need to show the most recent belt for every person 首先,您需要为每个人展示最新的皮带
  2. Then you need to show the people that has a belt 那你需要向有腰带的人展示

So, let's start. 所以,让我们开始吧。

Step 1.a. 步骤1.a. The most recent belt record for every user 每个用户的最新皮带记录

select b.*
from 
    belts as b
    inner join (
        select max(id) as maxId from belts group by userId
    ) as a on b.id = a.maxId

I am assuming that the id field is always incremental. 我假设id字段总是递增的。

Step 1.b. 步骤1.b. Join step (1.a.) with the user's data 将步骤(1.a.)与用户的数据结合起来

select u.*, b.*
from 
    users as u
    inner join (
    select b.*
    from 
        belts as b
        inner join (
            select max(id) as maxId from belts group by userId
        ) as a on b.id = a.maxId
    ) as b on u.userId = b.userId

Step 2. Select all users with a given belt 步骤2.选择所有具有给定腰带的用户

select u.*, b.*
from 
    users as u
    inner join (
    select b.*
    from 
        belts as b
        inner join (
            select max(id) as maxId from belts group by userId
        ) as a on b.id = a.maxId
    ) as b  on u.userId = b.userId
where
    b.belt_colour = 'brown'

Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM