在数据库查询过程中,有时候我们会遇到一些对聚合函数的结果进行过滤的情况,如果这个聚合函数本身又是个子查询获得的结果,这个时候再把它作为 一个where 条件语句的话,会导致查询效率极其的差。而通过with as 语法先把它“暂存”一下速度则会快很多。

基本用例如下:

1 我想做一个错题统计,先把错题ID和错题数查询出来

select 
	info.answerexeid AS exeid,//习题ID
	(select count	( T.answerexeid ) AS count from	w008_answer_paper_info T 
	where T.answerexeid = info.answerexeid and  T.iscorrect = 20 ) as wrongcount//错题数 
	w008_answer_paper_header h
	join w008_answer_paper_info info on h.ID = info.answerheaderid
	join w008_exercise_stem_info e on info.answerexeid = e.id 
	join w008_execrise_info i on info.answerexeid = i.exerciseid 
where
	h.userlongid = 2507032645091840 
	and info.iscorrect = 20

数据量不大,查询毫无压力

2 如果我想统计错误数大于12的情况,因为这个错题数是查询之后得到的结果,所以一般的做法是把当前查询结果作为一个“表”,再次查询,这次效率就慢了很多

2.1 没有where 条件

select t1.wrongcount
(select 
	info.answerexeid AS exeid,
	(select count	( T.answerexeid ) AS count from	w008_answer_paper_info T 
	where T.answerexeid = info.answerexeid and  T.iscorrect = 20 ) as wrongcount 
	w008_answer_paper_header h
	join w008_answer_paper_info info on h.ID = info.answerheaderid
	join w008_exercise_stem_info e on info.answerexeid = e.id 
	join w008_execrise_info i on info.answerexeid = i.exerciseid 
where
	h.userlongid = 2507032645091840 
	and info.iscorrect = 20

执行结果:

2.2 加上过滤条件,这一次执行时间在30s左右,这样的数据量,这个速度就太难以接受了

select t1.wrongcount
(select 
	info.answerexeid AS exeid,
	(select count	( T.answerexeid ) AS count from	w008_answer_paper_info T 
	where T.answerexeid = info.answerexeid and  T.iscorrect = 20 ) as wrongcount 
	w008_answer_paper_header h
	join w008_answer_paper_info info on h.ID = info.answerheaderid
	join w008_exercise_stem_info e on info.answerexeid = e.id 
	join w008_execrise_info i on info.answerexeid = i.exerciseid 
where
	h.userlongid = 2507032645091840 
	and info.iscorrect = 20
	where t1.wrongcount>12

执行结果:

3 改用with as 语法,耗时不到0.1秒,明显快了很多。

with	wronttab AS ( SELECT answerexeid, COUNT ( answerexeid ) AS wrongcount 
        FROM w008_answer_paper_info T WHERE iscorrect = '20' GROUP BY answerexeid )  
select 
	info.answerexeid AS exeid,
	(select count	( T.answerexeid ) AS count from	w008_answer_paper_info T 
	where T.answerexeid = info.answerexeid and  T.iscorrect = 20 ) as wrongcount 
	w008_answer_paper_header h
	join w008_answer_paper_info info on h.ID = info.answerheaderid
	join w008_exercise_stem_info e on info.answerexeid = e.id 
	join w008_execrise_info i on info.answerexeid = i.exerciseid 
	JOIN wronttab ON wronttab.answerexeid = info.answerexeid  
where
	h.userlongid = 2507032645091840 
	and info.iscorrect = 20
	and wronttab.wrongcount>12

执行结果:

其实with as  语法说白了,就是建了一个临时表,起到了视图的作用。避免子查询因嵌套太多导致性能慢的问题。

在数据库查询过程中,有时候我们会遇到一些对聚合函数的结果进行过滤的情况,如果这个聚合函数本身又是个子查询获得的结果,这个时候再把它作为 一个where 条件语句的话,会导致查询效率极其的差。而通过with as 语法先把它“暂存”一下速度则会快很多。基本用例如下:1 我想做一个错题统计,先把错题ID和错题数查询出来select info.answerexeid AS exeid,...
PostgreSQL WITH 子句 在 PostgreSQL 中,WITH 子句提供了一种编写辅助语句的方法,以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单,便于阅读。这些语句通常称为通用表表达式(Common Table Express, CTE),也可以当做一个为查询而存在的临时表。 WITH 子句是在多次执行子查询时特别有用,允许我们在查询中通过它的名称(可能是多次)引用它。 WITH 子句在使用前必须先定义。 WITH 查询的基础语法如下: name_for_summary_data AS ( SELECT Stat
with as 语法:WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会 被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数 据的部分。 特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话...
1.With As 含义 WITH AS短语,也叫做子查询部分(subquery factoring),可以定义一个SQL片断,该SQL片断会被整个SQL语句用到。可以使SQL语句的可读性更高,也可以在UNION ALL的不同部分,作为提供数据的部分。 对于UNION ALL,使用WITH AS定义了一个UNION ALL语句,当该片断被调用2次以上,优化器会自动将该WI...          WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分。          特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每 ```java String query = "SELECT column1 AS COLUMN1, column2 AS COLUMN2 FROM table"; ResultSet resultSet = statement.executeQuery(query); 在上述示例中,查询结果的字段别名被设置为大写,以便返回大写字段。 2. 在连接到数据库时,设置 `reWriteBatchedInserts` 参数为 `true`。这将强制 PostgreSQL-JDBC 驱动程序将所有 SQL 语句中的标识符转换为大写。例如: ```java Properties props = new Properties(); props.setProperty("user", "your_username"); props.setProperty("password", "your_password"); props.setProperty("reWriteBatchedInserts", "true"); String url = "jdbc:postgresql://localhost:5432/your_database"; Connection conn = DriverManager.getConnection(url, props); 通过上述设置,所有的查询语句中的字段将自动转换为大写。 无论使用哪种方法,查询结果中的字段将以大写形式返回。