SQL广泛用于数据分析和数据提取。简单易用,业内人士推崇虽然一开始写SQL还是挺容易的,但是错误率还是蛮高的。下面是大家在编写小新编译的SQL查询代码时常犯的5个错误。这些示例很短,看起来很简单。但是,在处理较大的查询时,这些错误不会立即显现出来。其中一些示例特定于AWSRedshift,而其他示例将出现在其他SQL数据库(Postgres、MySQL等)中。这些示例应该在本地数据库上运行,或者可以使用SQLFiddle在线运行。示例SQL查询可供下载。Set创建了两个临时表,其中包含一些条目以帮助处理该示例。销售表该表包含带有时间戳、产品、价格等的销售条目。注意键列是唯一的,其他列中的值可以重复(例如ts列)。DROPTABLEIFEXISTSsales;CREATETEMPORARYTABLEsales(keyvarchar(6),ttimestamp,productinteger,completedboolean,pricefloat);INSERTINTOsalesVALUES('sale_1','2019-11-0800:00',0,TRUE,1.1),('sale_2','2019-11-0801:00',0,FALSE,1.2),('sale_3','2019-11-0801:00',0,TRUE,1.3),('sale_4','2019-11-0801:00',1,FALSE,1.4),('sale_5','2019-11-0802:00',1,TRUE,1.5),('sale_6','2019-11-0802:00',1,TRUE,1.5);SELECT*FROMsales;每小时延迟表该表包含某一天的每小时延迟时间。请注意,下表中的ts列是唯一的。DROPTABLEIFEXISTShourly_delay;CREATETEMPORARYTABLEhourly_delay(ttimestamp,delayfloat);INSERTINTOhourly_delayVALUES('2019-11-0800:00',80.1),('2019-11-0801:00',100.2),('2019-11-0802.0870:);SELECT*FROMhourly_delay;1.检索按相同时间戳排序的每个产品的最新销售价格:SELECTpriceFROM(SELECTprice,row_number()OVER(PARTITIONBYproductORDERBYtsDESC)ASixFROMsales)ASq1WHEREix=1;上述查询的问题是多个销售具有相同的时间戳。对相同数据连续运行此查询可能会产生不同的结果。从下图可以看出,产品0在2019-11-11-0801:00卖出了两次,价格分别为1.2和1.3。用下一个错误修复此查询:)2.根据条件计算平均值计算完成销售的产品的平均价格。该值为(1.1+1.3+1.5+1.5)/4,即1.35。SELECTavg(price)FROM(SELECTCASEWHENcompleted=TRUETHENpriceelse0ENDApriceFROMsales)ASq1;运行查询时,该值为0.9。为什么?因为这个计算发生了:(1.1+0+1.3+0+1.5+1.5)/6是0.9。查询中的错误是您将0设置为不应包含的项目。应该使用NULL而不是0。目前,输出为预期的1.35。3.计算整数列的平均值计算包含整数的产品列的平均值。从销售中选择平均(产品);Product列中有3个0和3个1,估计平均值为0.5。大多数数据库(例如最新版本的Postgres)将返回0.5,但Redshift将返回0,因为它不会自动将产品列转换为浮动。因此,需要转换为float类型:SELECTavg(product::FLOAT)FROMsales;4.内连接假设要汇总每天的所有销售延迟,并计算每天的平均销售价格。选择t2.ts::DATE,sum(t2.delay),avg(t1.price)FROMhourly_delayASt2INNERJOINsalesASt1ONt1.ts=t2.tsGROUPBYt2.ts::DATE;结果错了!上面的查询将hourly_delay表中的delay列乘以一个倍数,如下所示。这是因为按时间戳连接,它在hourly_delay表中是唯一的,但在sales表中重复。要解决此问题,请在单独的子查询中计算每个表的统计信息,然后加入聚合。这使得时间戳在两个表中都是唯一的。SELECTt1.ts,daily_delay,avg_priceFROM(SELECTt2.ts::DATE,sum(t2.delay)ASdaily_delayFROMhourly_delayASt2GROUPBYt2.ts::DATE)ASt2INNERJOIN(SELECTts::DATEASts,avg(price)ASavg_priceFROMsalesGROUPBYts.:DATE)AStst5ONt向ORDERBY添加列上述错误的补救措施是显而易见的。将键列添加到ORDERBY以便可以对相同数据重复查询结果-快速修复。SELECTpriceFROM(SELECTprice,row_number()OVER(PARTITIONBYproductORDERBYts,keyDESC)ASixFROMsales)ASq1WHEREix=1;为什么查询结果和上次运行不一样?在执行“快速修复”时,键列被放置在ORDERBY中的错误位置。它应该在DESC语句之后,而不是之前。查询现在将返回第一次销售而不是最后一次销售。再做一次更正。SELECTproduct,priceFROM(SELECTproduct,price,row_number()OVER(PARTITIONBYproductORDERBYtsDESC,key)ASixFROMsales)ASq1WHEREix=1;此修复使结果可重复。以上就是大家经常踩到的SQL错误及解决方法。不知道大家有没有同感,或者对于SQL查询还有其他有趣的事情?记得分享给小新哦~
