[英]Running multiple queries in MySQL without using sub-query
I have two tables, one table called users
with, 我有两个表,一个叫做users
表,
fsname
emailaddress
and second table called attempts
with emailaddress
, score
and datetime
. 和第二个表调用了emailaddress
, score
和datetime
attempts
。
Now what I wanted to do is first order the attempts
table by datetime
and then pick then join the attempt
table with users
table if they have same emailaddress
and then pick the final attempts of each unique user. 现在我想要做的是首先按datetime
排序attempts
表,然后选择然后加入带有users
表的attempt
表,如果它们具有相同的emailaddress
,然后选择每个唯一用户的最终尝试。
In short, I have to pick the last attempt of each user by joining these table and this is the query that I have generated to achieve this, 简而言之,我必须通过加入这些表来选择每个用户的最后一次尝试,这是我为实现此目的而生成的查询,
$query = "SELECT
distinct users.fsname, users.emailaddress, attempts.score
FROM users
INNER JOIN attempts
ON users.emailaddress = attempts.emailaddress
ORDER BY datetime DESC";
This query first suppose to order the attempts
by datetime
and only pick values with distinct first name which is fsname
over here. 此查询首先假设按datetime
对attempts
进行排序,并且仅选择具有不同名字的值,即fsname
over here。
but When I execute the above query it returns the result with having non-unique values of fsname
eventhough I am using DISTINCT
with fsname
. 但是当我执行上面的查询时,它返回的结果具有非唯一的fsname
值,尽管我正在使用带有fsname
DISTINCT
。
Can anyone please tell me why DISTINCT
is not working to only pick distinct fsname
? 任何人都可以告诉我为什么DISTINCT
不工作只选择不同的fsname
?
I have tried both DISTINCT fsname
and DISTINCT(fsname)
but none of these are working. 我已经尝试了DISTINCT fsname
和DISTINCT(fsname)
但这些都没有用。
It doesn't work as you think it should and the documentation explains the meaning of DISTINCT
: it's about distinct rows : 它不会像您认为的那样工作, 文档解释了DISTINCT
的含义:它是关于不同的行 :
The
ALL
andDISTINCT
options specify whether duplicate rows should be returned.ALL
和DISTINCT
选项指定是否应返回重复的行。ALL
(the default) specifies that all matching rows should be returned, including duplicates.ALL
(默认值)指定应返回所有匹配的行,包括重复行。DISTINCT
specifies removal of duplicate rows from the result set.DISTINCT
指定从结果集中删除重复的行。 It is an error to specify both options. 指定两个选项都是错误的。DISTINCTROW
is a synonym forDISTINCT
.DISTINCTROW
是同义词DISTINCT
。
(source: http://dev.mysql.com/doc/refman/5.7/en/select.html ) (来源: http : //dev.mysql.com/doc/refman/5.7/en/select.html )
You need to group the rows by user in order to get a single row for each user but, unfortunately, you cannot get their most recent score this way. 您需要按用户对行进行分组,以便为每个用户获取一行,但遗憾的是,您无法通过这种方式获得最新的分数。 You can get the maximum, minimum, average score and other computed values. 您可以获得最大值,最小值,平均值和其他计算值。 Check the list of GROUP BY
aggregate functions . 检查GROUP BY
聚合函数列表。
This is the query that gets the values you need: 这是获取所需值的查询:
SELECT u.fsname, u.emailaddress, la.score
FROM users u
INNER JOIN attempts la # 'la' from 'last attempt'
ON u.emailaddress = la.emailaddress
LEFT JOIN attempts mr # 'mr' from 'more recent' (than last attempt)
ON la.emailaddress = mr.emailaddress AND la.datetime < mr.datetime
WHERE mr.datetime IS NULL
It joins table users
(aliased as u
) with table attempts
(aliased as la
, short for "last attempt") using emailaddress
as the matching column. 它使用emailaddress
作为匹配列,将表users
(别名为u
)与表attempts
(别名为la
,“最后一次尝试”的缩写)连接起来。 It's the join you already have in your query, I added the aliases because they help you write less from that point on. 这是你在查询中已经拥有的连接,我添加了别名,因为它们可以帮助你减少从那一点开始写的内容。
Next, it joins the attempts
table again (aliased as mr
from " more recent than the last attempt"). 接下来,加入attempts
再次表(别名为mr
从“比上一次尝试更近 ”)。 It matches each attempt from la
with all the attempts from mr
of the same user (identified by their emailaddress
) and that have a more recent datetime
. 它匹配来自la
每次尝试以及来自同一用户的mr
(由他们的emailaddress
标识)的所有尝试并且具有更新的datetime
。 The LEFT JOIN
ensures that each row from la
matches at least one row from mr
. LEFT JOIN
确保la
中的每一行与mr
至少一行匹配。 The rows from la
that do not have a match in mr
are the rows that have the biggest values of datetime
for each emailaddress
. la
中没有匹配的行是mr
是每个emailaddress
具有最大datetime
值的行。 They are matched with rows full of NULL
(for the mr
part). 它们与满NULL
行匹配(对于mr
部分)。
Finally, the WHERE
clause keeps only the rows that have NULL
in the datetime
column of the row selected from mr
. 最后, WHERE
子句仅保留从mr
选择的行的datetime
列中具有NULL
的行。 These are the rows that matched the most recent entries from la
for each value of emailaddress
. 这些是与emailaddress
每个值匹配la
最新条目的行。
In order to run fast this query ( any query! ) needs indexes on the columns used in the JOIN
, WHERE
, GROUP BY
and ORDER BY
clauses. 为了快速运行此查询( 任何查询! )需要在JOIN
, WHERE
, GROUP BY
和ORDER BY
子句中使用的列上的索引。
You should not use emailaddress
in table attempts
to identify the user. 您不应在表attempts
使用emailaddress
来识别用户。 You should have a PK
(primary key) on table users
and use that as a FK
(foreign key) in table attempts
(and other tables that refer to a user). 您应该在表users
使用PK
(主键),并在表attempts
(以及引用用户的其他表)中将其用作FK
(外键)。 If emailaddress
is the PK
of table users
change it to an UNIQUE INDEX
and use a new INTEGER AUTO INCREMENT
ed column userId
as PK
instead. 如果emailaddress
是表的users
PK
,则将其更改为UNIQUE INDEX
并使用新的INTEGER AUTO INCREMENT
ed列userId
作为PK
。 The indexes on numeric columns are faster and use less space than the indexes on string columns. 数字列上的索引比字符串列上的索引更快,占用的空间更少。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.