5个编写SQL查询时常出现的错误分别是什么

65次阅读
没有评论

共计 3092 个字符,预计需要花费 8 分钟才能阅读完成。

这篇文章将为大家详细讲解有关 5 个编写 SQL 查询时常出现的错误分别是什么,文章内容质量较高,因此丸趣 TV 小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

SQL 被广泛应用于数据分析和数据提取。易上手,受到业内人士的一致好评

尽管刚开始编写 SQL 相当容易,但是出错率也是相当的高。

下面是小芯整理的,在编写 SQL 查询代码时大家经常犯的 5 个错误。

示例很短,可能看起来很简单。但是,在处理更大的查询时,这些错误可就不会一目了然了。其中一些示例是特定于 AWS  Redshift 的,而另一些则会出现在其他 SQL 数据库(Postgres、MySQL 等)。这些示例应该在本地数据库上运行,或者可以使用 SQLFiddle 在线运行。

示例 SQL 查询可下载。

设定

创建两个临时表,其中有几个条目有助于处理示例。

Sales 表

该表包含带有时间戳、产品、价格等的销售条目。请注意,key 列是唯一的,其他列中的值可以重复(例如 ts 列)。

DROP TABLE IF EXISTSsales; CREATE TEMPORARY TABLE sales ( key varchar(6), ts timestamp, product integer, completed boolean, price float );INSERT INTO sales VALUES (sale_1 ,  2019-11-08 00:00 , 0, TRUE, 1.1), (sale_2 ,  2019-11-08 01:00 , 0, FALSE,1.2), (sale_3 ,  2019-11-08 01:00 , 0, TRUE,1.3), (sale_4 ,  2019-11-08 01:00 , 1, FALSE,1.4), (sale_5 ,  2019-11-08 02:00 , 1, TRUE,1.5), (sale_6 ,  2019-11-08 02:00 , 1, TRUE,1.5);SELECT * FROM sales;

Hourly delay 表

该表包含某一天每小时的延迟时间。请注意,ts 列在下表中是唯一的。

DROP TABLE IF EXISTShourly_delay; CREATE TEMPORARY TABLE hourly_delay ( ts timestamp, delay float ); INSERT INTO hourly_delay VALUES (2019-11-08 00:00 , 80.1), (2019-11-08 01:00 , 100.2), (2019-11-08 02:00 , 70.3);SELECT* FROM hourly_delay;

1. 按相同时间戳排序

检索每种产品最近一次的售价:

SELECT price FROM (SELECT price, row_number() OVER (PARTITION BYproduct ORDER BY ts DESC) AS ix FROM sales) ASq1 WHERE ix = 1;

以上查询的问题是多个销售具有相同的时间戳。此查询在相同数据上的连续运行可能得出不同的结果。下图可见,产品 0 在 2019-11-11-08  01:00 有两次销售,价格分别为 1.2 和 1.3。

用下一个错误修复这个查询:)

2. 根据条件计算平均值

计算完成销售的产品的平均价格。值是(1.1 + 1.3 + 1.5 + 1.5)/ 4,即 1.35。

SELECT avg(price) FROM (SELECT CASE WHEN completed = TRUETHEN price else 0 END AS price FROM sales) ASq1;

当运行查询时,值为 0.9。为什么? 因为发生了这一计算:(1.1+0+1.3+0+1.5+1.5)/ 6 是 0.9。查询中的错误是,将 0 设置为不应包含的项。应使用 NULL 而不是 0。

SELECT avg(price) FROM (SELECT CASE WHEN completed = TRUETHEN price else NULL END AS price FROMsales) AS q1;

当前,输出和预计一样是 1.35。

3. 计算整数列的平均值

计算含有整数的 product 列的平均值。

SELECT avg(product) FROM sales;

Product 列中有 3 个 0 和 3 个 1,预估平均值为 0.5。大多数数据库 (例如最新版本的 Postgres) 将返回 0.5,但是 Redshift 将返回 0,因为它不会自动将 product 列强制转换为 float。因此需要将其强制转换为 float 类型:

SELECT avg(product::FLOAT) FROM sales;

4. 内连接

假设要对每天的所有销售延迟进行汇总,并计算每天的平均销售价格。

SELECT t2.ts::DATE, sum(t2.delay),avg(t1.price) FROM hourly_delay AS t2 INNER JOIN sales ASt1 ON t1.ts = t2.ts GROUP BY t2.ts::DATE;

结果是错误的! 以上查询将 hourly_delay 表中的 delay 列乘以倍数,如下图所示。这是因为按时间戳连接,该时间戳在 hourly_delay 表中是唯一的,但在 sales 表中会重复。

为了修复这个问题,要在一个单独的子查询中为每个表计算统计信息,然后连接汇总。这使得时间戳在两个表中都是唯一的。

SELECT t1.ts, daily_delay, avg_price FROM (SELECT t2.ts::DATE, sum(t2.delay) ASdaily_delay FROM hourly_delay AS t2 GROUP BYt2.ts::DATE) AS t2 INNER JOIN (SELECTts::DATE AS ts, avg(price) AS avg_price FROM sales GROUPBY ts::DATE) AS t1 ON t1.ts = t2.ts;

5. 将列添加到 ORDER BY

对上述错误的补救是显而易见的。将 key 列添加到 ORDER BY,这样一来,查询结果就可以在相同数据上重复出现 mdash; mdash; 快速修复。

SELECT price FROM (SELECT price, row_number() OVER (PARTITION BYproduct ORDER BY ts, key DESC) AS ix FROMsales) AS q1 WHERE ix = 1;

为什么查询结果不同于上一次运行? 在进行“快速修复”时,key 列被放在了 ORDER  BY 中的错误位置。它应该在 DESC 语句之后,而不是之前。查询现在将返回第一笔销售,而不是最后一笔销售。再进行一次修正。

SELECT product, price FROM (SELECT product, price, row_number() OVER (PARTITION BYproduct ORDER BY ts DESC, key) AS ix FROMsales) AS q1 WHERE ix = 1;

本次修复使结果可重复。

关于 5 个编写 SQL 查询时常出现的错误分别是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-19发表,共计3092字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)