天道酬勤,学无止境

SQL Prompt教程:旧式联接语法(ST001)

SQL Prompt是一款实用的SQL语法提示工具。SQL Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读--当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码效率。此外,用户还可根据需要进行自定义,使之以预想的方式工作。

使用旧式联接语法没有任何优势。如果SQL提示标识了它在旧版代码中的使用,则重写语句以使用ANSI标准的连接语法将简化和改进代码。

SQL Prompt实现了一个静态代码分析规则ST001,该规则将在开发和测试工作期间自动检查代码是否出现非ANSI标准的JOIN语法。

SQL的“旧样式” Microsoft / Sybase JOIN样式已使用= *和* =语法,已弃用,不再使用。当数据库引擎级别为10(SQL Server 2008)或更高版本(兼容级别100)时,使用此语法的查询将失败。ANSI-89表引用列表(FROM表A,表B)仍然仅是INNER JOIN的ISO标准。这些样式都不值得使用。自ANSI SQL-92发布以来,就一直最好指定所需的连接类型:INNER,LEFT OUTER,RIGHT OUTER,FULL OUTER和CROSS。尽管可以选择任何受支持的JOIN样式,而不会影响SQL Server使用的查询计划,但使用ANSI标准语法将使您的代码更易于理解,更一致,并且可移植到其他关系数据库系统中。

旧式外部联接已过时

当SQL Server从Sybase派生时,它继承了其旧的非标准Transact-SQL语法用于联接,其中分别包括左和右外部联接的=和=语法。

从第一个表(外部联接的“外部成员”)中选择的左外部联接运算符* =,满足语句限制的所有行。仅当该行的连接条件匹配时,第二个表(“内部成员”)才会生成值;否则,它提供空值。相反,对于右外部联接运算符= *,第二个表成为“外部成员”,从中选择所有符合条件的行。

即使支持这些语法,也存在一些限制。您不能在HAVING子句中包含Transact-SQL外部联接,也不能在与旧式外部联接相同的表达式中执行其他INNER JOIN。此外,外部连接语法(* =或= *)并不总是给出正确的结果,有时在指定外部连接时使用交叉连接。

无论如何,此语法在SQL Server 2005及更高版本中已被弃用,并在SQL Server 2008中停止工作。清单1的目的是查询pubs数据库,其目的是返回没有相应作者的所有标题。

--all titles without an author
SELECT ti.title + Coalesce( ' (' + ti.type + ') -' + ti.pub_id,' (Unknown category)') AS publication
  FROM dbo.titles AS ti, dbo.titleauthor AS Ta
     where ti.title_id *= Ta.title_id
     AND Ta.title_id IS NULL;

清单1
但是,除非将兼容性级别设置为90,否则它将在SQL Server 2008或更高版本中失败。此设置仅在SQL Server 2012之前可用:

Msg 102, Level 15, State 1, Line 6
Incorrect syntax near '*='.

如果仍然有使用此语法的查询,则在升级到SQL Server 2012之前,必须重写它们以使用清单2中所示的ANSI标准语法,因为不再支持兼容性级别90。

--all titles without an author
SELECT ti.title + Coalesce( ' (' + ti.type + ') -' + ti.pub_id,' (Unknown category)') AS publication
  FROM dbo.titles AS ti
    LEFT OUTER JOIN dbo.titleauthor AS Ta
      ON ti.title_id = Ta.title_id
  WHERE Ta.title_id IS NULL
ORDER BY ti.title

清单2

得到以下结果:

ed9be5fb2ca708aa3f5aea526deb7c1a.png

支持老式的内部联接,但没有优势

内部联接的表引用语法是ANSI标准的一部分,因此仍受支持。清单3使用了它,并将返回与其发布者居住在同一城市的所有作者。

–(旧语法)与发布者居住在同一城市的作者

  --(Old Syntax)authors that live in the same city as their publishers
SELECT 
  authors.au_fname + ' ' + authors.au_lname AS Author, 
  publishers.pub_name AS Publisher, publishers.city
  FROM dbo.authors, dbo.titleauthor, dbo.titles, dbo.publishers
  WHERE authors.au_id = titleauthor.au_id 
    AND titleauthor.title_id = titles.title_id 
    AND titles.pub_id = publishers.pub_id 
    AND publishers.city = authors.city

清单3

清单4显示了使用ANSI-92标准的相同代码,其中我们使联接类型明确。

--(Newer Syntax) authors that live in the same city as their publishers
SELECT 
  authors.au_fname+ ' '+authors.au_lname AS Author, 
  publishers.pub_name AS Publisher, publishers.city
  FROM dbo.authors
    INNER JOIN dbo.titleauthor
      ON authors.au_id = titleauthor.au_id
    INNER JOIN dbo.titles
      ON titleauthor.title_id = titles.title_id
    INNER JOIN dbo.publishers
      ON titles.pub_id = publishers.pub_id
  WHERE publishers.city = authors.city

清单4

两者给出的结果相同,执行计划相同。

25a17466de637f0a2d936ce8c31df39f.png

但是,广泛接受的是,旧式的“引文列表”内部联接语法很难阅读和理解,因此比新语法更容易出错。

无论如何,即使仍支持该旧式语法,也没有遗憾的理由。例如,您如何使用旧风格的联接语法确定与发布者居住在不同城市的作者所占的百分比?这将是一个使用方括号和子查询的外观复杂的查询。使用更新的语法,它很容易编写,也很容易理解其逻辑。

--proportion of authors who live in the same city as their publishers
SELECT 
  Sum(CASE WHEN publishers.city IS NULL THEN 1 ELSE 0 END) AS [different city],
  Count(*) AS total, 
  (Sum(CASE WHEN publishers.city IS NULL THEN 1 ELSE 0 END) * 100)
      / Count(*) AS percentage
  FROM dbo.authors
    INNER JOIN dbo.titleauthor
      ON authors.au_id = titleauthor.au_id
    INNER JOIN dbo.titles
      ON titleauthor.title_id = titles.title_id
    LEFT OUTER JOIN dbo.publishers
      ON titles.pub_id = publishers.pub_id AND publishers.city = authors.city

清单5

结论

将旧式联接语法留在遗留代码中没有任何优势。如果发现此代码异味,它将改进并简化代码以重写语句以使用ANSI标准连接语法


如果您对SQL Prompt感兴趣,可以在慧都网免费下载最新试用版

标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 什么时候应该在内部联接上使用交叉应用?(When should I use cross apply over inner join?)
    问题 使用CROSS APPLY的主要目的是什么? 我已经读过(模糊地通过Internet上的帖子),如果您正在分区,则在选择大型数据集时, cross apply可能会更有效。 (想起分页) 我也知道, CROSS APPLY不需要UDF作为右表。 在大多数INNER JOIN查询(一对多关系)中,我可以重写它们以使用CROSS APPLY ,但是它们总是给我等效的执行计划。 在CROSS APPLY在INNER JOIN也将起作用的情况下, CROSS APPLY时,谁能给我一个很好的例子? 编辑: 这是一个简单的示例,其中执行计划完全相同。 (向我展示它们的不同之处和cross apply的更快/更有效的地方) create table Company ( companyId int identity(1,1) , companyName varchar(100) , zipcode varchar(10) , constraint PK_Company primary key (companyId) ) GO create table Person ( personId int identity(1,1) , personName varchar(100) , companyId int , constraint FK_Person_CompanyId foreign
  • 在Oracle上使用内部联接更新语句(Update statement with inner join on Oracle)
    问题 我有一个在MySQL中运行良好的查询,但是在Oracle上运行该查询时,出现以下错误: SQL错误:ORA-00933:SQL命令未正确结束 00933. 00000-“ SQL命令未正确结束” 查询是: UPDATE table1 INNER JOIN table2 ON table1.value = table2.DESC SET table1.value = table2.CODE WHERE table1.UPDATETYPE='blah'; 回答1 该语法在Oracle中无效。 你可以这样做: UPDATE table1 SET table1.value = (SELECT table2.CODE FROM table2 WHERE table1.value = table2.DESC) WHERE table1.UPDATETYPE='blah' AND EXISTS (SELECT table2.CODE FROM table2 WHERE table1.value = table2.DESC); 或者您可以执行以下操作: UPDATE (SELECT table1.value as OLD, table2.CODE as NEW FROM table1 INNER JOIN table2 ON table1.value = table2.DESC WHERE
  • java.util.Date与java.sql.Date(java.util.Date vs java.sql.Date)
    问题 java.util.Date与java.sql.Date :什么时候使用?为什么? 回答1 恭喜,您已经通过JDBC达到了我最喜欢的功能:Date类处理。 基本上,数据库通常至少支持三种形式的日期时间字段,即日期,时间和时间戳。 它们每个在JDBC中都有一个对应的类,并且每个都扩展了java.util.Date 。 这三个中的每一个的快速语义如下: java.sql.Date对应于SQL DATE,这表示它存储年,月和日,而时,分,秒和毫秒被忽略。 此外, sql.Date不受时区限制。 java.sql.Time对应于SQL TIME,并且应该很明显,它仅包含有关hour,minutes,seconds和milliseconds的信息。 java.sql.Timestamp对应于SQL TIMESTAMP,这是精确到纳秒级的日期(请注意util.Date仅支持毫秒! ),并且具有可自定义的精度。 与这三种类型相关联使用JDBC驱动程序时,最常见的错误之一是对这些类型的处理不正确。 这意味着sql.Date是时区特定的, sql.Time包含当前的年,月和日等。 最后:使用哪个? 确实取决于字段的SQL类型。 PreparedStatement具有用于所有三个值的设置器, #setDate()是#setDate()的一个, sql.Date #setTime()是sql
  • MySQL-基于SELECT查询的UPDATE查询(MySQL - UPDATE query based on SELECT Query)
    问题 我需要检查(从同一张表中)基于日期时间的两个事件之间是否存在关联。 一组数据将包含某些事件的结束日期时间,另一组数据将包含其他事件的开始日期时间。 如果第一个事件在第二个事件之前完成,那么我想将它们链接起来。 到目前为止,我有: SELECT name as name_A, date-time as end_DTS, id as id_A FROM tableA WHERE criteria = 1 SELECT name as name_B, date-time as start_DTS, id as id_B FROM tableA WHERE criteria = 2 然后我加入他们: SELECT name_A, name_B, id_A, id_B, if(start_DTS > end_DTS,'VALID','') as validation_check FROM tableA LEFT JOIN tableB ON name_A = name_B 然后,可以基于我的validation_check字段运行嵌套了SELECT的UPDATE查询吗? 回答1 您实际上可以通过以下两种方式之一执行此操作: MySQL更新联接语法: UPDATE tableA a INNER JOIN tableB b ON a.name_a = b.name_b SET
  • 如何在Spark SQL中控制分区大小(How to control partition size in Spark SQL)
    问题 我需要使用Spark SQL HiveContext从Hive表加载数据并加载到HDFS中。 默认情况下,SQL输出中的DataFrame具有2个分区。 为了获得更多的并行性,我需要从SQL中获得更多的分区。 HiveContex没有重载方法来获取分区数参数。 RDD的重新分区会导致改组并导致更多的处理时间。 > val result = sqlContext.sql("select * from bt_st_ent") 具有以下日志输出: Starting task 0.0 in stage 131.0 (TID 297, aster1.com, partition 0,NODE_LOCAL, 2203 bytes) Starting task 1.0 in stage 131.0 (TID 298, aster1.com, partition 1,NODE_LOCAL, 2204 bytes) 我想知道有什么方法可以增加SQL输出的分区大小。 回答1 Spark <2.0 : 您可以使用Hadoop配置选项: mapred.min.split.size 。 mapred.max.split.size 以及HDFS块大小,以控制基于文件系统的格式的分区大小*。 val minSplit: Int = ??? val maxSplit: Int = ??? sc
  • sql加入维恩图(sql joins as venn diagram)
    问题 我在理解sql中的连接时遇到了麻烦,并遇到了此图像,我认为这可能会对我有所帮助。 问题是我不完全了解它。 例如,图像右上角的联接将整个B圆圈染成红色,但仅将A重叠。该图像使圆圈B看起来像是sql语句的主要焦点,但是sql语句本身,从A开头(从A中选择,然后加入B),向我传达了相反的印象,即A将成为sql语句的焦点。 同样,下面的图像仅包含来自B圈的数据,那么为什么join语句中完全包含A? 问题:右上角顺时针工作并在中心结束,有人可以提供有关每个sql映像表示的更多信息,解释 a)为什么在每种情况下都需要联接(例如,特别是在没有从A或B取得数据的情况下,即只有A或B而不是都用彩色涂色的情况) b)和其他任何可以阐明为什么图像很好地表示sql的细节 回答1 我认为您的主要内在困惑是(例如)当仅以红色突出显示A ,您将其理解为“查询仅从A返回数据”,但实际上这意味着“查询仅返回那些A的数据。在A有记录的情况下。 查询可能仍包含从B.数据(对于情况下, B没有一个记录,查询将取代NULL )。 同样,下面的图像仅包含来自B圈的数据,那么为什么join语句中完全包含A? 如果您的意思是-图像中A完全为白色,并且B的部分有一个红色的月牙形,但不与A重叠,那么: A在查询中出现的原因是, A是如何查找B中需要排除的记录。 (如果A没有出现在查询中,则维恩图将没有A ,它只会显示B
  • 子查询vs联接(Subqueries vs joins)
    问题 我重构了我们从另一家公司继承来的应用程序的缓慢部分,以使用内部联接而不是像以下子查询: WHERE id IN (SELECT id FROM ...) 重构查询的运行速度大约快100倍。 (约50秒,约0.3秒)我希望有所改善,但是谁能解释为什么如此剧烈? where子句中使用的列均已建立索引。 SQL是否在where子句中每行执行一次查询? 更新-说明结果: 区别在于“(())中的id”查询的第二部分- 2 DEPENDENT SUBQUERY submission_tags ref st_tag_id st_tag_id 4 const 2966 Using where vs 1带有连接的索引行: SIMPLE s eq_ref PRIMARY PRIMARY 4 newsladder_production.st.submission_id 1 Using index 回答1 “相关子查询”(即,其中where条件取决于从包含查询的行获得的值的子查询)将为每一行执行一次。 一个不相关的子查询(其中where条件独立于所包含查询的子查询)将在开始时执行一次。 SQL引擎会自动进行此区分。 但是,是的,解释计划将为您提供肮脏的细节。 回答2 您为每行运行一次子查询,而联接发生在索引上。 回答3 这是一个如何在MySQL 6.0中评估子查询的示例。
  • 显式与隐式SQL连接(Explicit vs implicit SQL joins)
    问题 显式内部连接与隐式内部连接是否存在效率差异? 例如: SELECT * FROM table a INNER JOIN table b ON a.id = b.id; 与 SELECT a.*, b.* FROM table a, table b WHERE a.id = b.id; 回答1 在性能方面,它们是完全相同的(至少在SQL Server中)。 PS:请注意,自SQL Server 2005起不建议使用IMPLICIT OUTER JOIN语法。(仍支持该问题中使用的IMPLICIT INNER JOIN语法) 弃用“旧样式” JOIN语法:只是部分事情 回答2 就我个人而言,我更喜欢联接语法,因为它可以使表更清楚地说明联接表以及联接方式。 尝试比较较大的SQL查询,从8个不同的表中进行选择,然后在where中进行大量筛选。 通过使用联接语法,您可以将联接表的部分分离到要过滤行的部分。 回答3 在MySQL 5.1.51上,两个查询都具有相同的执行计划: mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid; +----+-------------+-------+------+---------------+------+---------+--------------
  • 在SQL或MySQL中不使用JOIN关键字的联接有问题吗?(Is there something wrong with joins that don't use the JOIN keyword in SQL or MySQL?)
    问题 当我开始编写数据库查询时,我还不知道JOIN关键字,自然地,我只是扩展了我已经知道的内容并编写了这样的查询: SELECT a.someRow, b.someRow FROM tableA AS a, tableB AS b WHERE a.ID=b.ID AND b.ID= $someVar 现在,我知道这与INNER JOIN相同,我在代码中找到了所有这些查询,并问自己是否应该重写它们。 它们有臭味吗?还是还好? 编辑: 我的答案摘要:此查询没有问题,但使用关键字很可能会使代码更具可读性/可维护性。 我的结论:我不会更改旧的查询,但将来会更正我的写作风格并使用关键字。 感谢您的回答! 回答1 在某些常见情况下,仅使用WHERE过滤联接可能效率极低。 例如: SELECT * FROM people p, companies c WHERE p.companyID = c.id AND p.firstName = 'Daniel' 大多数数据库将完全按字面意义执行此查询,首先采用people和companies表的笛卡尔积,然后按具有匹配的companyID id和id字段的数据进行过滤。 尽管完全不受约束的产品并不存在于内存中,而是仅存在片刻,但它的计算确实需要一些时间。 更好的方法是在相关时用JOIN将约束分组。 这不仅主观上更容易阅读,而且效率更高。 因此:
  • LINQ的左外连接(LEFT OUTER JOIN in LINQ)
    问题 如何在不使用join-on-equals-into子句的情况下在C#LINQ中对对象执行左外部联接? 有什么办法可以通过where子句做到这一点? 正确的问题:因为内部联接很容易,我有这样的解决方案 List<JoinPair> innerFinal = (from l in lefts from r in rights where l.Key == r.Key select new JoinPair { LeftId = l.Id, RightId = r.Id}) 但是对于左外部联接,我需要一个解决方案。 我的是这样的,但没有用 List< JoinPair> leftFinal = (from l in lefts from r in rights select new JoinPair { LeftId = l.Id, RightId = ((l.Key==r.Key) ? r.Id : 0 }) JoinPair是一个类: public class JoinPair { long leftId; long rightId; } 回答1 如上所述: 101个LINQ样本-左外连接 var q = from c in categories join p in products on c.Category equals p.Category into ps from p
  • SQL Server中的LEFT JOIN与LEFT OUTER JOIN(LEFT JOIN vs. LEFT OUTER JOIN in SQL Server)
    问题 LEFT JOIN和LEFT OUTER JOIN什么区别? 回答1 根据文档:FROM(Transact-SQL): <join_type> ::= [ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ] JOIN 关键字OUTER被标记为可选(括在方括号中)。 在这种特定情况下,是否指定OUTER都没有区别。 请注意,尽管join子句的其他元素也被标记为可选元素,但将它们省略会有所不同。 例如, JOIN子句的整个type-part是可选的,在这种情况下,如果您仅指定JOIN ,则默认值为INNER 。 换句话说,这是合法的: SELECT * FROM A JOIN B ON A.X = B.Y 以下是等效语法的列表: A LEFT JOIN B A LEFT OUTER JOIN B A RIGHT JOIN B A RIGHT OUTER JOIN B A FULL JOIN B A FULL OUTER JOIN B A INNER JOIN B A JOIN B 还要看看我在另一个SO问题上留下的答案:SQL左联接与FROM行上的多个表? 回答2 要回答您的问题,LEFT JOIN和LEFT OUTER JOIN之间没有区别,它们与所说的完全相同... 在顶层
  • INNER JOIN ON与WHERE子句(INNER JOIN ON vs WHERE clause)
    问题 为简单起见,假设所有相关字段都不为NOT NULL 。 你可以做: SELECT table1.this, table2.that, table2.somethingelse FROM table1, table2 WHERE table1.foreignkey = table2.primarykey AND (some other conditions) 要不然: SELECT table1.this, table2.that, table2.somethingelse FROM table1 INNER JOIN table2 ON table1.foreignkey = table2.primarykey WHERE (some other conditions) 这两个在MySQL是否以相同的方式工作? 回答1 INNER JOIN是您应该使用的ANSI语法。 通常认为它更具可读性,尤其是当您连接许多表时。 如有需要,也可以轻松地将其替换为OUTER JOIN 。 WHERE语法更面向关系模型。 两个表JOIN ed的结果是表的笛卡尔积,将对其应用过滤器,该过滤器仅选择连接列匹配的那些行。 使用WHERE语法更容易看到这一点。 以您的示例为例,在MySQL(通常在SQL中)中,这两个查询是同义词。 另外,请注意,MySQL还具有STRAIGHT_JOIN子句。
  • 内联与何处(Inner join vs Where)
    问题 两者之间的性能(在oracle中)是否有区别 Select * from Table1 T1 Inner Join Table2 T2 On T1.ID = T2.ID 和 Select * from Table1 T1, Table2 T2 Where T1.ID = T2.ID ? 回答1 不! 相同的执行计划,请看下面两个表: CREATE TABLE table1 ( id INT, name VARCHAR(20) ); CREATE TABLE table2 ( id INT, name VARCHAR(20) ); 使用内部联接的查询的执行计划: -- with inner join EXPLAIN PLAN FOR SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.id = t2.id; SELECT * FROM TABLE (DBMS_XPLAN.DISPLAY); -- 0 select statement -- 1 hash join (access("T1"."ID"="T2"."ID")) -- 2 table access full table1 -- 3 table access full table2 以及使用WHERE子句的查询的执行计划。 -- with where clause
  • Oracle的加(+)表示法和ansi JOIN表示法之间的区别?(Difference between Oracle's plus (+) notation and ansi JOIN notation?)
    问题 什么是使用Oracle的加符号之间的差额(+)在ANSI标准join的符号? 性能上有区别吗? 加号是否已弃用? 回答1 在AFAIK中,仅显示(+)符号是为了向后兼容,因为Oracle在将ANSI标准用于连接之前将其首次亮相。 它特定于Oracle,并且当存在等效的符合标准的版本时,应避免在新代码中使用它。 似乎两者之间存在差异,并且(+)表示法具有ANSI join语法所没有的限制。 Oracle自己建议您不要使用(+)表示法。 Oracle®数据库SQL语言参考11g第1版(11.1)中的完整描述: Oracle建议您使用FROM子句OUTER JOIN语法,而不要使用Oracle join运算符。 使用Oracle连接运算符(+)外部连接查询受以下规则和限制的约束,这些规则和限制不适用于FROM子句的OUTER JOIN语法: 您不能在还包含FROM子句连接语法的查询块中指定(+)运算符。 (+)运算符只能出现在WHERE子句中,或者在FROM子句的左相关(指定TABLE子句时)的上下文中出现,并且只能应用于表或视图的列。 如果A和B通过多个联接条件联接,则必须在所有这些条件中使用(+)运算符。 如果不这样做,那么Oracle数据库将仅返回由简单联接产生的行,而不会发出警告或错误来通知您没有外部联接的结果。 如果在外部查询中指定一个表,而在内部查询中指定另一个表,则(
  • ANSI JOIN与非ANSI JOIN查询的执行方式会有所不同吗?(Will ANSI JOIN vs. non-ANSI JOIN queries perform differently?)
    问题 我在大约7000行T-SQL存储过程中有业务逻辑,其中大多数具有下一个JOIN语法: SELECT A.A, B.B, C.C FROM aaa AS A, bbb AS B, ccc AS C WHERE A.B = B.ID AND B.C = C.ID AND C.ID = @param 如果我将这样的查询替换为以下内容,是否可以提高性能: SELECT A.A, B.B, C.C FROM aaa AS A JOIN bbb AS B ON A.B = B.ID JOIN ccc AS C ON B.C = C.ID AND C.ID = @param 还是一样? 回答1 这两个查询是相同的,除了第二个查询是ANSI-92 SQL语法,而第一个查询是未合并join子句的较旧的SQL语法。 尽管您可能想检查一下,但它们应该产生完全相同的内部查询计划。 出于多种原因,您应该使用ANSI-92语法 JOIN子句的使用将关系逻辑与过滤器逻辑(WHERE)分开,因此更简洁易懂。 该特定查询无关紧要,但是在某些情况下,较旧的外部联接语法(使用+)含糊不清,因此查询结果依赖于实现,或者根本无法解析该查询。 这些在ANSI-92中不会发生这是一个好习惯,因为当今大多数开发人员和dba都将使用ANSI-92,因此您应该遵循该标准。 当然,所有现代查询工具都会生成ANSI-92。 正如
  • SQL仅选择列上具有最大值的行[重复](SQL select only rows with max value on a column [duplicate])
    问题 想要改善这篇文章吗? 提供此问题的详细答案,包括引文和为什么您的答案正确的解释。 答案不够详细的答案可能会被编辑或删除。 这个问题已经在这里有了答案: 检索每个组中的最后一个记录-MySQL (29个答案) 2年前关闭。 我有此表用于文档(此处为简化版): +------+-------+--------------------------------------+ | id | rev | content | +------+-------+--------------------------------------+ | 1 | 1 | ... | | 2 | 1 | ... | | 1 | 2 | ... | | 1 | 3 | ... | +------+-------+--------------------------------------+ 如何为每个ID选择一行,并且仅选择最大转速? 使用上述数据,结果应包含两行: [1, 3, ...]和[2, 1, ..] 。 我正在使用MySQL 。 目前,我在while循环中使用检查功能来检测并覆盖结果集中的旧版本。 但这是获得结果的唯一方法吗? 没有SQL解决方案吗? 更新作为答案提示,有一个SQL的解决方案,并且这里sqlfiddle演示。 更新2 在添加上面的sqlfiddle之后
  • SQL JOIN和不同类型的JOIN(SQL JOIN and different types of JOINs)
    问题 什么是SQL JOIN ,什么是不同类型? 回答1 W3schools的插图: 回答2 什么是SQL JOIN ? SQL JOIN是一种从两个或多个数据库表中检索数据的方法。 有什么不同的SQL JOIN ? 共有五个JOIN 。 他们是 : 1. JOIN or INNER JOIN 2. OUTER JOIN 2.1 LEFT OUTER JOIN or LEFT JOIN 2.2 RIGHT OUTER JOIN or RIGHT JOIN 2.3 FULL OUTER JOIN or FULL JOIN 3. NATURAL JOIN 4. CROSS JOIN 5. SELF JOIN 1. JOIN或INNER JOIN: 在这种JOIN ,我们获得了两个表中都与条件匹配的所有记录,并且两个表中不匹配的记录均未报告。 换句话说, INNER JOIN基于以下事实:仅应列出两个表中的匹配条目。 请注意,一个JOIN没有任何其他JOIN关键字(如INNER , OUTER , LEFT等)是一个INNER JOIN 。 换句话说, JOIN是INNER JOIN的语法糖(请参阅:JOIN和INNER JOIN之间的区别)。 2.外连接: OUTER JOIN检索 一个表中的匹配行与另一表中的所有行匹配,或者所有表中的所有行匹配(是否匹配)。 共有三种外连接: 2
  • 在MySQL查询中,为什么要使用join而不是在哪里?(In MySQL queries, why use join instead of where?)
    问题 似乎要合并两个或多个表,我们可以使用join或where。 一个相对于另一个的优点是什么? 回答1 任何涉及多个表的查询都需要某种形式的关联,以将结果从表“ A”链接到表“ B”。 传统的(ANSI-89)方法是: 在FROM子句中列出逗号分隔列表中涉及的表在WHERE子句中编写表之间的关联SELECT * FROM TABLE_A a, TABLE_B b WHERE a.id = b.id 这是使用ANSI-92 JOIN语法重写的查询: SELECT * FROM TABLE_A a JOIN TABLE_B b ON b.id = a.id 从性能角度来看: 在受支持的地方(Oracle 9i +,PostgreSQL 7.2 +,MySQL 3.23 +,SQL Server 2000+),使用任何一种语法都不会对其他语法产生性能上的好处。 优化器将它们视为相同的查询。 但是更复杂的查询可以从使用ANSI-92语法中受益: 控制JOIN顺序的能力-扫描表的顺序能够在加入表格之前在表格上应用过滤条件 从维护的角度来看: 在ANSI-89上使用ANSI-92 JOIN语法的原因有很多: 更具可读性,因为JOIN标准与WHERE子句分开不太可能错过JOIN标准对除INNER之外的JOIN类型的一致语法支持,使查询易于在其他数据库上使用
  • LINQ to SQL中的内部联接的语法是什么?(What is the syntax for an inner join in LINQ to SQL?)
    问题 我正在编写LINQ to SQL语句,并且正在使用C#中带有ON子句的常规内部联接的标准语法。 您如何在LINQ to SQL中表示以下内容: select DealerContact.* from Dealer inner join DealerContact on Dealer.DealerID = DealerContact.DealerID 回答1 它类似于: from t1 in db.Table1 join t2 in db.Table2 on t1.field equals t2.field select new { t1.field2, t2.field3} 为表提供一个明智的名称和字段,这将是一个很好的例子。 :) 更新 我认为对于您的查询,这可能更合适: var dealercontacts = from contact in DealerContact join dealer in Dealer on contact.DealerId equals dealer.ID select contact; 由于您在寻找联系人,而不是经销商。 回答2 并且由于我更喜欢​​表达式链语法,因此您可以通过以下方式实现它: var dealerContracts = DealerContact.Join(Dealer, contact => contact
  • 如何使用方法语法在linq中连接到sql?(How to do a join in linq to sql with method syntax?)
    问题 我已经在LINQ to SQL示例中看到了很多有关如何进行查询语法联接的示例,但是我想知道如何使用方法语法进行联接吗? 例如我该怎么做以下 var result = from sc in enumerableOfSomeClass join soc in enumerableOfSomeOtherClass on sc.Property1 equals soc.Property2 select new { SomeClass = sc, SomeOtherClass = soc } 用.Join() ? 谁能说明或提供另一个简单的例子? 回答1 var result = from sc in enumerableOfSomeClass join soc in enumerableOfSomeOtherClass on sc.Property1 equals soc.Property2 select new { SomeClass = sc, SomeOtherClass = soc }; 等效于: var result = enumerableOfSomeClass .Join(enumerableOfSomeOtherClass, sc => sc.Property1, soc => soc.Property2, (sc, soc) => new { SomeClass =