繁体   English   中英

在MySQL中运行多个查询而不使用子查询

[英]Running multiple queries in MySQL without using sub-query

我有两个表,一个叫做users表,

fsname
emailaddress

和第二个表调用了emailaddressscoredatetime attempts

现在我想要做的是首先按datetime排序attempts表,然后选择然后加入带有users表的attempt表,如果它们具有相同的emailaddress ,然后选择每个唯一用户的最终尝试。

简而言之,我必须通过加入这些表来选择每个用户的最后一次尝试,这是我为实现此目的而生成的查询,

$query = "SELECT 
            distinct users.fsname, users.emailaddress, attempts.score 
            FROM users 
            INNER JOIN attempts 
            ON users.emailaddress = attempts.emailaddress 
            ORDER BY datetime DESC";

此查询首先假设按datetimeattempts进行排序,并且仅选择具有不同名字的值,即fsname over here。

但是当我执行上面的查询时,它返回的结果具有非唯一的fsname值,尽管我正在使用带有fsname DISTINCT

任何人都可以告诉我为什么DISTINCT不工作只选择不同的fsname

我已经尝试了DISTINCT fsnameDISTINCT(fsname)但这些都没有用。

它不会像您认为的那样工作, 文档解释了DISTINCT的含义:它是关于不同的

ALLDISTINCT选项指定是否应返回重复的行。 ALL (默认值)指定应返回所有匹配的行,包括重复行。 DISTINCT指定从结果集中删除重复的行。 指定两个选项都是错误的。 DISTINCTROW是同义词DISTINCT

(来源: http//dev.mysql.com/doc/refman/5.7/en/select.html

您需要按用户对行进行分组,以便为​​每个用户获取一行,但遗憾的是,您无法通过这种方式获得最新的分数。 您可以获得最大值,最小值,平均值和其他计算值。 检查GROUP BY聚合函数列表。

查询

这是获取所需值的查询:

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

这个怎么运作

它使用emailaddress作为匹配列,将表users (别名为u )与表attempts (别名为la ,“最后一次尝试”的缩写)连接起来。 这是你在查询中已经拥有的连接,我添加了别名,因为它们可以帮助你减少从那一点开始写的内容。

接下来,加入attempts再次表(别名为mr从“比上一次尝试更近 ”)。 它匹配来自la每次尝试以及来自同一用户的mr (由他们的emailaddress标识)的所有尝试并且具有更新的datetime LEFT JOIN确保la中的每一行与mr至少一行匹配。 la中没有匹配的行是mr是每个emailaddress具有最大datetime值的行。 它们与满NULL行匹配(对于mr部分)。

最后, WHERE子句仅保留从mr选择的行的datetime列中具有NULL的行。 这些是与emailaddress每个值匹配la最新条目的行。

表现评论

为了快速运行此查询( 任何查询! )需要在JOINWHEREGROUP BYORDER BY子句中使用的列上的索引。

您不应在表attempts使用emailaddress来识别用户。 您应该在表users使用PK (主键),并在表attempts (以及引用用户的其他表)中将其用作FK (外键)。 如果emailaddress是表的users PK ,则将其更改为UNIQUE INDEX并使用新的INTEGER AUTO INCREMENT ed列userId作为PK 数字列上的索引比字符串列上的索引更快,占用的空间更少。

暂无
暂无

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

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