SQL Prompt是一款实用的SQL语法提示工具。SQL Prompt根据数据库的对象名称、语法和代码片段自动进行检索,为用户提供合适的代码选择。自动脚本设置使代码简单易读——当开发者不大熟悉脚本时尤其有用。SQL Prompt安装即可使用,能大幅提高编码效率。
编写GROUP BY子句对于SQL程序员来说,是一种非常常见但又单调乏味的活动。本文描述SQL Prompt将为您填充它,查询返回所有非聚合列。
“你见过这个用非聚合列自动填充GROUP BY的新功能吗?”我的同事在安装了一个新版本的SSMS不久后大声说道。我没有,但我很好奇。在我的职业生涯中,我写过成千上万的汇总查询,所以这听起来好像可以节省我一些时间。
我在SSMS中搜索了我用于测试SQL Server新版本的虚拟机,但是没有找到。事实证明,我的测试虚拟机没有安装SQL Prompt,毕竟这不是新的SSMS功能,而是那些“隐藏的”SQL Prompt增强的功能之一。
手动填写GROUP BY
假设我需要在WideWorldImporters数据库上写一个查询,以获得已订购的项目总和,按邮政编码以及客户帐户开立的年份分组。
按照典型的方式,我首先填写表格及其连接条件。我输入“or”来查找与订单相关的表格,甚至不必知道它们存在于Sales模式中。
我扩展SELECT列表,最初只返回我需要使用的基本行。我应用我首选的提示格式样式,查询看起来像这样:
SELECT Customers.DeliveryPostalCode AS PostalCode, YEAR(Customers.AccountOpenedDate) AS AccountOpenYear, OrderLines.Quantity FROM Sales.OrderLines JOIN Sales.Orders ON Orders.OrderID = OrderLines.OrderID JOIN Sales.Customers ON Customers.CustomerID = Orders.CustomerID;
查询返回几十万行,其中一小部分样本如下所示:
PostalCode AccountOpenYear Quantity ---------- --------------- ----------- 90398 2013 7 90005 2013 7 90313 2013 7 90434 2013 7
我想查看总订单数量,按客户交货邮政编码和客户开立帐户的年份,因此最终SELECT清单如下所示:
SELECT Customers.DeliveryPostalCode AS PostalCode, YEAR(Customers.AccountOpenedDate) AS AccountOpenYear, SUM(OrderLines.Quantity) AS TotalOrderQuantity
这只是一个GROUP BY子句,通常,我只是复制并粘贴SELECT子句中的非聚合列,并用GROUP BY替换SELECT:
GROUP BY Customers.DeliveryPostalCode AS PostalCode, YEAR(Customers.AccountOpenedDate) AS AccountOpenYear
最后,我只是删掉别名来给出这样的最终查询:
SELECT Customers.DeliveryPostalCode AS PostalCode, YEAR(Customers.AccountOpenedDate) AS AccountOpenYear, OrderLines.Quantity FROM Sales.OrderLines JOIN Sales.Orders ON Orders.OrderID = OrderLines.OrderID JOIN Sales.Customers ON Customers.CustomerID = Orders.CustomerID GROUP BY Customers.DeliveryPostalCode, YEAR(Customers.AccountOpenedDate;
总而言之,这是一个繁琐的过程。
使用SQL提示符自动填充GROUP BY
与SQL语句的所有子句一样,SQL Prompt帮助填写GROUP BY;我以前没注意过!只需在键入GROUP BY的子句后按空格键,如图所示。
选择所有非聚合列,它将使用以下列表达式填充GROUP BY子句:
GROUP BY YEAR(Customers.AccountOpenedDate), Customers.DeliveryPostalCode;
或者,如上图所示,您可以单独选择非聚合列。如果要添加其他分组,例如按客户打开帐户的月份,只需添加MONTH(Customers.AccountOpenedDate) AS AccountOpenMonth到SELECT子句,删除现有GROUP BY子句,然后自动重新填充列表达式。该GROUP BY子句现在看起来像这样:
GROUP BY YEAR(Customers.AccountOpenedDate), MONTH(Customers.AccountOpenedDate), Customers.DeliveryPostalCode;
在某些情况下,您的SELECT子句中的值可能在聚合函数中,但不需要在GROUP BY子句中。例如,假设我们更改SELECT查询以包含两个新列,在以下代码中以粗体文本突出显示。一个是文字值,另一个是对现有列中的列进行计算GROUP BY:
SELECT Customers.DeliveryPostalCode AS PostalCode, YEAR(Customers.AccountOpenedDate) AS AccountOpenYear, MONTH(Customers.AccountOpenedDate) AS AccountOpenMonth, <strong>1 AS Value,</strong> <strong>YEAR(Customers.AccountOpenedDate) - 1 AS PreviousAccountOpenYear,</strong> SUM(OrderLines.Quantity) AS TotalOrderQuantity FROM Sales.OrderLines JOIN Sales.Orders ON Orders.OrderID = OrderLines.OrderID JOIN Sales.Customers ON Customers.CustomerID = Orders.CustomerID GROUP BY YEAR(Customers.AccountOpenedDate), MONTH(Customers.AccountOpenedDate), Customers.DeliveryPostalCode;
此查询将按原样执行,因为我们不需要在文字上进行分组,也不需要对仅使用GROUP BY中已有的列或表达式的表达式进行分组。
但是,如果我们删除现有GROUP BY子句,并让SQL Prompt自动填充它,那么它看起来会略有不同:
GROUP BY YEAR(Customers.AccountOpenedDate), MONTH(Customers.AccountOpenedDate), <strong> YEAR(Customers.AccountOpenedDate) - 1,</strong> Customers.DeliveryPostalCode
这是一种罕见的情况,几乎肯定不会对查询的执行造成任何影响,但要注意这一点。
这是我们完成的查询,但如果您想订购输出,请尝试输入ORDER BY,看看会出现什么!
结论
一旦安装了SQL Prompt,您就会立即意识到它是如何增强SSMS的本机智能感知功能的,但这可能使您无法看到隐藏在工具各个部分中的许多其他功能。通常情况下,我只是偶然发现它们,或者是同事提醒我的时候。这只是我发现自己一旦意识到它的存在就经常使用的一个功能的另一个精华!
编写GROUP BY对于SQL程序员来说,是一种非常常见但又乏味的活动。我总是说,用软件取代那个乏味的东西。