package my.test.command.dml;
import my.test.TestBase;
public class SelectTest extends TestBase {
public static void main(String[] args) throws Exception {
new SelectTest().start();
}
@Override
public void init() throws Exception {
prop.setProperty("MODE", "DB2"); // 支持SYSDUMMY1、supportOffsetFetch
// prop.setProperty("PAGE_SIZE", "128");
// prop.setProperty("DEFAULT_TABLE_ENGINE",
// "org.h2.mvstore.db.MVTableEngine");
// prop.setProperty("TRACE_LEVEL_FILE", "10");
// prop.setProperty("TRACE_LEVEL_SYSTEM_OUT", "20");
// prop.setProperty("PAGE_SIZE", "1024");
// prop.setProperty("FILE_LOCK", "FS");
}
@Override
public void startInternal() throws Exception {
// createTable();
// parseSelectSimpleSelectPart();
// readTableFilter();
// readJoin();
// parseEndOfQuery();
// parseSelectSimpleFromPart();
//
// queryFlat();
select_init();
// queryGroup();
// queryGroupSorted();
//
// queryQuick();
//
// queryDistinct();
// prepare();
// queryWithoutCache();
// preparePlan();
}
void createTable() throws Exception {
stmt.executeUpdate("drop table IF EXISTS mytable,natural_join_test_table1,natural_join_test_table2,mytable1,mytable2");
// stmt.executeUpdate("create table IF NOT EXISTS mytable(id int primary key, name varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS mytable(id int, name varchar(500), age int)");
stmt.executeUpdate("ALTER TABLE mytable ALTER COLUMN id SELECTIVITY 10");
stmt.executeUpdate("ALTER TABLE mytable ALTER COLUMN name SELECTIVITY 10");
// stmt.executeUpdate("ALTER TABLE mytable ADD CONSTRAINT NAME_UNIQUE UNIQUE(name,id)");
stmt.executeUpdate("create index IF NOT EXISTS mytable_id_index on mytable(id)");
stmt.executeUpdate("create index IF NOT EXISTS mytable_age_index on mytable(age)");
stmt.executeUpdate("create index IF NOT EXISTS mytable_name_age_index on mytable(name,age)");
stmt.executeUpdate("create table IF NOT EXISTS mytable1(id1 int primary key, name1 varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS mytable2(id2 int primary key, name2 varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS mytable3(id3 int primary key, name3 varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS mytable4(id4 int primary key, name4 varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS mytable5(id5 int primary key, name5 varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS mytable6(id6 int primary key, name6 varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS mytable7(id7 int primary key, name7 varchar(500))");
stmt.executeUpdate("create table IF NOT EXISTS natural_join_test_table1(id int primary key, name varchar(500), age1 int)");
stmt.executeUpdate("create table IF NOT EXISTS natural_join_test_table2(id int primary key, name varchar(500), age2 int)");
for (int i = 1; i <= 0; i++) {
if (i % 2 == 0)
stmt.executeUpdate("insert into mytable(id, name) values(" + i + ", '" + i + "abcdef1234')");
else
stmt.executeUpdate("insert into mytable(id, name) values(" + i + ", null)");
stmt.executeUpdate("insert into natural_join_test_table1(id, name) values(" + i + ", 'abcdef1234')");
stmt.executeUpdate("insert into natural_join_test_table2(id, name) values(" + i + ", 'abcdef1234')");
stmt.executeUpdate("insert into mytable1(id1, name1) values(" + i + ", 'abcdef1234')");
stmt.executeUpdate("insert into mytable2(id2, name2) values(" + i * 10 + ", 'abcdef1234')");
}
stmt.executeUpdate("insert into mytable(id, name, age) values(" + 1 + ", '" + 1 + "abcdef1234', 10)");
stmt.executeUpdate("insert into mytable(id, name, age) values(" + 1 + ", '" + 1 + "abcdef12343', 10)");
stmt.executeUpdate("insert into mytable(id, name, age) values(" + 1 + ", '" + 2 + "abcdef1234', 20)");
stmt.executeUpdate("insert into mytable(id, name, age) values(" + 2 + ", '" + 3 + "abcdef1234', 30)");
stmt.executeUpdate("insert into mytable(id, name, age) values(" + 2 + ", '" + 4 + "abcdef1234', 40)");
stmt.executeUpdate("insert into mytable(id, name, age) values(" + 3 + ", '" + 5 + "abcdef1234', 50)");
stmt.executeUpdate("insert into mytable(id, name, age) values(" + 3 + ", '" + 6 + "abcdef1234', 60)");
// 测试org.h2.command.dml.Select.queryGroup(int, LocalResult)
sql = "SELECT DISTINCT count(*),max(id),min(id),sum(id) FROM mytable ";
// 测试org.h2.command.dml.Select.queryQuick(int, ResultTarget)
// sql = "SELECT DISTINCT count(*) FROM mytable ";
// sql = "SELECT DISTINCT LENGTH(NAME) FROM mytable ";
// 测试org.h2.command.dml.Select.queryDistinct(ResultTarget, long)
sql = "select distinct name from mytable";
sql = "select name from mytable where id=3";
sql = "select max(name) from mytable";
}
// 测试试org.h2.command.Parser.parseSelectSimpleSelectPart(Select)
void parseSelectSimpleSelectPart() {
sql = "select 2";
sql = "select TOP 10 DISTINCT * from mytable";
sql = "select LIMIT 2 5 *, id, name n, name as n2 from mytable";
sql = "select LIMIT 2 5 t.* from mytable t";
sql = "select * from mytable";
sql = "select 1 union select 1";
sql = "select (select 1)";
sql = "select 1";
sql = "select id, name from mytable where id>0";
sql = "select public.t.* from mytable as t where id>199";
sql = "select public.t.id, *, name from mytable as t where id>199 group by id having id>99 order by t.id desc";
sql = "select id,name from mytable as t where id>199 group by id having id>99 order by t.id desc";
sql = "select name from mytable as t where id>199 group by id having id>99 order by t.id desc";
// sql =
// "select id, name from mytable as t where id>199 order by t.id desc";
// sql = "select name from mytable as t where id>199 order by id desc";
// sql =
// "select distinct name from mytable as t where id>199 order by id desc";
// sql = "select distinct name from mytable order by id desc";
// sql = "select name from mytable order by id desc";
// sql = "SELECT 1 AS A FROM DUAL ORDER BY -A"; //有错 Column "A" not
// found; SQL statement:
// sql = "SELECT 1 AS A FROM DUAL ORDER BY A";
sql = "select * from mytable1 t1 LEFT OUTER JOIN mytable2 t2 on t1.id1=t2.id2 where t1.id1>100 group by t1.id1 having t1.id1>150 order by t1.id1 desc";
// sql =
// "select * from mytable1 t1 RIGHT OUTER JOIN mytable2 t2 on t1.id1=t2.id2 where t1.id1>100 group by t1.id1 having t1.id1>150 order by t1.id1 desc";
// sql = "select id, name from mytable where id>198";
sql = "select id1,name2 from mytable1 t1 LEFT OUTER JOIN mytable2 t2 on t1.id1=t2.id2 where t1.id1>100 group by id1,name1 having t1.id1>150 order by t1.id1 desc";
sql = "select id1,name2 from mytable1 t1 LEFT OUTER JOIN mytable2 t2 on t1.id1=t2.id2 where t1.id1>100 group by id1,name1 having id2>150 order by t1.id1 desc, name2";
sql = "select count(id) from mytable";
sql = "select distinct name from mytable";
}
// 测试org.h2.command.Parser.readTableFilter(boolean)
void readTableFilter() throws Exception {
sql = "FROM (select 1, 2) SELECT * ";
executeQuery();
sql = "FROM (select 1, 2) as t SELECT * ";
executeQuery();
sql = "FROM ((select 1, 2)) SELECT * ";
sql = "FROM (((select 1, 2))) SELECT * ";
sql = "FROM (mytable) SELECT * ";
executeQuery();
sql = "FROM (mytable1 RIGHT OUTER JOIN mytable2 ON mytable1.id1=mytable2.id2) AS t SELECT * ";
sql = "FROM VALUES(1, 'Hello'), (2, 'World') AS t SELECT * ";
executeQuery();
sql = "FROM mytable(index mytable_age_index) SELECT * "; // 目前index mytable_age_index并没有实现
executeQuery();
sql = "FROM SYSTEM_RANGE(1,100) SELECT * ";
executeQuery();
sql = "FROM GENERATE_SERIES(1,100,10) SELECT * ";
executeQuery();
sql = "FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World')) SELECT * ";
executeQuery();
sql = "FROM USER() SELECT * "; // 函数返回值类型必须是RESULT_SET
tryExecuteQuery();
sql = "FROM DUAL SELECT * ";
executeQuery();
sql = "FROM SYSDUMMY1 SELECT * "; // 要加prop.setProperty("MODE", "DB2")
executeQuery();
// 下面两者是一样的
sql = "FROM mytable as t SELECT * ";
executeQuery();
sql = "FROM mytable t SELECT * ";
executeQuery();
}
void readJoin() throws Exception {
}
// 以下部分测试org.h2.command.Parser.parseEndOfQuery(Query)
void parseEndOfQuery() throws Exception {
sql = "select id,name,age from mytable order by 1, =? DESC";
ps = conn.prepareStatement(sql);
ps.setInt(1, 2);
rs = ps.executeQuery();
printResultSet(rs);
sql = "select id,name,age from mytable order by ? DESC";
ps = conn.prepareStatement(sql);
ps.setInt(1, 2);
rs = ps.executeQuery();
printResultSet(rs);
sql = "select id,name from mytable order by =1 DESC";
executeQuery();
sql = "select id,name from mytable order by -1 DESC";
executeQuery();
sql = "select name from mytable order by id";
// sql = "(select name from mytable order by id)";
// sql =
// "(select name from (select name from mytable where id=? and name=?) where id=?)";
// sql =
// "(select name from mytable where id=? and id in(select name from mytable where id=? and name=?))";
// ps = conn.prepareStatement(sql);
// ps.setInt(1, 1);
// ps.setInt(2, 1);
// ps.setString(3, "abc");
// rs = ps.executeQuery();
// union时LIMIT、ordey by、FOR UPDATE不能放在子句中,要放在最后
// 比如这条是错误的:
// sql =
// "select name1 from mytable1 order by name1 union select name2 from mytable2";
// 要改成这样:
sql = "select name1 from mytable1 union select name2 from mytable2 order by name1";
sql = "select id,name from mytable order by id DESC";
sql = "select id,name from mytable order by -1";
// sql = "select id,name from mytable order by ?";
// ps = conn.prepareStatement(sql);
// ps.setInt(1, -1);
// rs = ps.executeQuery();
sql = "select id,name from mytable order by =-1 DESC";
executeQuery();
sql = "select id,name from mytable order by -1 DESC"; // 负数表示降序,再加DESC就表示降序的降序,实际就是升序
sql = "select id,name from mytable order by -2 NULLS FIRST";
sql = "select id,name from mytable order by -2 NULLS LAST";
// OFFSET 要跟ROW或ROWS,不能少
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROW";
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROWS";
// 下面两行等价 FETCH FIRST ROW ONLY和FETCH NEXT ROW ONLY一样
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROWS FETCH FIRST ROW ONLY";
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROWS FETCH NEXT ROW ONLY";
// 下面两行等价
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROWS FETCH NEXT 1 ROW ONLY";
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROWS FETCH NEXT 4 ROWS ONLY";
// 下面两行等价
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROWS FETCH FIRST 1 ROW ONLY";
sql = "select id,name from mytable order by -2 NULLS LAST OFFSET 2 ROWS FETCH FIRST 4 ROWS ONLY";
sql = "select id,name from mytable order by id LIMIT 2 OFFSET 3"; // OFFSET按0算,OFFSET
// 3就是从第4条记录开始
sql = "select id,name from mytable order by id LIMIT 3, 2"; // 跟上面效果一样"3, 2"表示OFFSET
// 3 LIMIT 2
sql = "select id,name from mytable order by id LIMIT 3, 5 SAMPLE_SIZE 2"; // SAMPLE_SIZE
// 2时不输出记录
sql = "select id,name from mytable order by id LIMIT 3, 5 SAMPLE_SIZE 6"; // SAMPLE_SIZE
// 6时输出记录了
sql = "select id,name from mytable FOR UPDATE";
sql = "select id,name from mytable FOR READ ONLY WITH RS"; // "FOR READ ONLY WITH RS"可有可无
executeQuery();
}
// 测试org.h2.command.Parser.parseSelectSimpleFromPart(Select)
// org.h2.command.Parser.parseJoinTableFilter(TableFilter, Select)
// org.h2.command.Parser.readJoin(TableFilter, Select, boolean, boolean)
void parseSelectSimpleFromPart() {
sql = "SELECT * FROM mytable1 RIGHT OUTER JOIN mytable2 ON mytable1.id1 = mytable2.id2";
sql = "SELECT * FROM mytable1 LEFT OUTER JOIN mytable2 ON mytable1.id1 = mytable2.id2";
// 不支持FULL JOIN
// sql =
// "SELECT * FROM mytable1 FULL JOIN mytable2 ON mytable1.id1 = mytable2.id2";
// INNER JOIN和JOIN一样
sql = "SELECT * FROM mytable1 INNER JOIN mytable2 ON mytable1.id1 = mytable2.id2";
sql = "SELECT * FROM mytable1 JOIN mytable2 ON mytable1.id1 = mytable2.id2";
sql = "SELECT * FROM mytable1 JOIN mytable2";
// CROSS JOIN不能跟ON
// sql =
// "SELECT * FROM mytable1 CROSS JOIN mytable2 ON mytable1.id1 = mytable2.id2";
// sql = "SELECT * FROM mytable1 CROSS JOIN mytable2";
// NATURAL JOIN不能跟ON
// sql =
// "SELECT * FROM mytable1 NATURAL JOIN mytable2 ON mytable1.id1 = mytable2.id2";
// sql =
// "SELECT * FROM natural_join_test_table1 NATURAL JOIN natural_join_test_table2";
// sql =
// "SELECT * FROM mytable1 INNER JOIN mytable2 ON mytable1.id1 = mytable2.id2 LEFT OUTER JOIN mytable3";
// sql =
// "FROM ((select 1) union (select 1)) RIGHT OUTER JOIN ((select 2) union (select 2)) SELECT * ";
//
// sql =
// "SELECT * FROM mytable1 RIGHT OUTER JOIN mytable2 LEFT OUTER JOIN mytable3 INNER JOIN mytable4 "
// + "JOIN mytable5 CROSS JOIN mytable6 NATURAL JOIN mytable7 "
// +
// " ON mytable7.id7 = mytable6.id6 ON mytable6.id6 = mytable5.id5 ON mytable5.id5 = mytable4.id4"
// +
// " ON mytable4.id4 = mytable3.id3 ON mytable3.id3 = mytable2.id2 ON mytable2.id2 = mytable1.id1";
//
// //ON在最外面是不对的
// sql =
// "SELECT * FROM mytable1 RIGHT OUTER JOIN mytable2 LEFT OUTER JOIN mytable3 INNER JOIN mytable4 "
// + "JOIN mytable5 CROSS JOIN mytable6" //
// + " ON mytable5.id5 = mytable4.id4" //
// +
// " ON mytable4.id4 = mytable3.id3 ON mytable3.id3 = mytable2.id2 ON mytable2.id2 = mytable1.id1";
//
// sql =
// "SELECT * FROM mytable1 RIGHT OUTER JOIN mytable2 ON mytable2.id2 = mytable1.id1";
//
// sql =
// "SELECT * FROM mytable3 INNER JOIN mytable4 ON mytable4.id4 = mytable3.id3";
//
// sql =
// "SELECT * FROM mytable1 RIGHT OUTER JOIN mytable2 LEFT OUTER JOIN mytable3 INNER JOIN mytable4 "
// + "JOIN mytable5 CROSS JOIN mytable6 NATURAL JOIN mytable7 " +
// " ON mytable5.id5 = mytable4.id4"
// +
// " ON mytable4.id4 = mytable3.id3 ON mytable3.id3 = mytable2.id2 ON mytable2.id2 = mytable1.id1";
//
// //ON在最里面就没问题
// sql = "SELECT * FROM mytable1"//
// + " RIGHT OUTER JOIN mytable2 ON mytable2.id2 = mytable1.id1"//
// + " LEFT OUTER JOIN mytable3 ON mytable3.id3 = mytable2.id2"//
// + " INNER JOIN mytable4 ON mytable4.id4 = mytable3.id3"//
// + " JOIN mytable5 ON mytable5.id5 = mytable4.id4"//
// + " CROSS JOIN mytable6"//
// + " NATURAL JOIN mytable7";
}
void select_init() throws Exception {
// expandColumnList();
// Query_initOrder();
// sql = "select age, count(id) from mytable group by id,name";
// executeQuery();
//
// sql = "select age, count(id), name from mytable group by id,name";
// executeQuery();
//
// sql = "select age, count(id), name from mytable group by name, 2";
// executeQuery();
//
// 测试havingIndex
// sql = "select id,count(id) from mytable group by id having id=3";
// executeQuery();
// sql = "SELECT X/3 AS A, COUNT(*) FROM SYSTEM_RANGE(1, 1) GROUP BY A HAVING A>=0";
// executeQuery();
// sql = "SELECT X/3 AS A, COUNT(*) FROM SYSTEM_RANGE(1, 10) GROUP BY A HAVING A>=1";
// executeQuery();
//
// sql = "select id,age, count(*),name from mytable group by id,age HAVING id>0";
// executeQuery();
//
sql = "SELECT id AS A FROM mytable where A>=0";
// executeQuery();
sql = "SELECT id/3 AS A, COUNT(*) FROM mytable GROUP BY A HAVING A>=0";
executeQuery();
}
void expandColumnList() throws Exception {
// 不允许这样
sql = "select mytable.* from mytable t";
// 只能这样
sql = "select t.* from mytable t";
executeQuery();
stmt.executeUpdate("drop table IF EXISTS emptytable");
stmt.executeUpdate("create table IF NOT EXISTS emptytable()");
sql = "select 2, *, 1 from emptytable";
executeQuery();
sql = "select *,name from emptytable, mytable";
executeQuery();
sql = "select * from mytable";
executeQuery();
sql = "select public.mytable.*, name from mytable";
sql = "select public.mytable.*, name from mytable as t";
// 对于myschema.t.*这样的语法,即使myschema不存在,在parser中也没有报错的
// 而是在org.h2.command.dml.Select.expandColumnList()中报错
// 因为mytable没有指定schema作为前缀,所以默认是public,这跟myschema不同,所以认为Table "T" not
// found;
sql = "select DISTINCT myschema.t.*, name from mytable as t";
sql = "select * from mytable1, mytable2";
executeQuery();
sql = "select id, name from natural_join_test_table1, natural_join_test_table2";
sql = "select * from natural_join_test_table1 natural join natural_join_test_table2";
executeQuery();
}
void Query_initOrder() throws Exception {
sql = "select name as n, id from mytable order by 1*1";
executeQuery();
// 列名不存在的检查是放在org.h2.expression.ExpressionColumn.optimize(Session)里做
// Column "ID3" not found;
sql = "select name,id3 from mytable order by 1*1";
tryExecuteQuery();
sql = "select distinct name from mytable order by id desc";
tryExecuteQuery();
sql = "select name,id from mytable t order by 1*1, t.id";
executeQuery();
sql = "select name,id from mytable order by 1 desc";
executeQuery();
sql = "select name,id as i from mytable order by i";
executeQuery();
sql = "select name,id as i from mytable t order by t.i";
tryExecuteQuery();
sql = "select name,id as i from mytable t order by mytable.i";
tryExecuteQuery();
sql = "select name,id as i from mytable t order by t.id";
executeQuery();
stmt.executeUpdate("CREATE CONSTANT IF NOT EXISTS ONE VALUE 1");
sql = "select name,ONE from mytable order by name";
sql = "select name,ONE from mytable where name = 'abc' || '123'";
}
void queryGroup() throws Exception {
sql = "select id from mytable group by id";
sql = "select id from mytable group by id having id>2";
sql = "select id, count(id) from mytable group by id having id>2";
executeQuery();
// sql = "select name, count(name) from mytable group by name having name>2";
// executeQuery();
sql = "select id, count(id) from mytable group by id";
sql = "select count(id) from mytable group by id";
// sql = "select id,name,count(id) from mytable where id>0";
sql = "select id,count(id) from mytable where id>0";
// sql = "select id,count(id) from mytable where id>0 group by id";
sql = "select max(id), count(id) from mytable where id>1";
executeQuery();
stmt.executeUpdate("delete from mytable");
stmt.executeUpdate("insert into mytable(id, name) values(" + 1 + ", '" + 1 + "abcdef1234')");
stmt.executeUpdate("insert into mytable(id, name) values(" + 1 + ", '" + 1 + "abcdef1234')");
stmt.executeUpdate("insert into mytable(id, name) values(" + 2 + ", '" + 3 + "abcdef1234')");
stmt.executeUpdate("insert into mytable(id, name) values(" + 2 + ", '" + 4 + "abcdef1234')");
stmt.executeUpdate("insert into mytable(id, name) values(" + 3 + ", '" + 5 + "abcdef1234')");
stmt.executeUpdate("insert into mytable(id, name) values(" + 3 + ", '" + 6 + "abcdef1234')");
sql = "select id,name,count(id),sum(id) from mytable where id>0 group by id,name having id<3";
// sql =
// "select id,count(id) from mytable where id>2 group by id having id=3";
sql = "select id,count(id) from mytable t where id>2 group by id having t.id=3";
// stmt.executeUpdate("set @X=6");
sql = "SELECT 6/3 AS A, COUNT(*) FROM SYSTEM_RANGE(1, 10) GROUP BY A HAVING A>2";
executeQuery();
}
void queryGroupSorted() throws Exception {
stmt.executeUpdate("drop table IF EXISTS queryGroupSorted");
stmt.executeUpdate("create table IF NOT EXISTS queryGroupSorted(id int, name varchar(500), age int)");
stmt.executeUpdate("create index IF NOT EXISTS queryGroupSorted_index_id on queryGroupSorted(id)");
stmt.executeUpdate("create index IF NOT EXISTS queryGroupSorted_index_name on queryGroupSorted(name)");
stmt.executeUpdate("create index IF NOT EXISTS queryGroupSorted_index_id_name_age on queryGroupSorted(id,name,age)");
stmt.executeUpdate("insert into queryGroupSorted(id, name, age) values(1, 'a', 10)");
stmt.executeUpdate("insert into queryGroupSorted(id, name, age) values(2, 'b', 10)");
stmt.executeUpdate("insert into queryGroupSorted(id, name, age) values(1, 'a', 20)");
stmt.executeUpdate("insert into queryGroupSorted(id, name, age) values(2, 'b', 10)");
stmt.executeUpdate("insert into queryGroupSorted(id, name, age) values(3, 'a', 20)");
stmt.executeUpdate("insert into queryGroupSorted(id, name, age) values(3, 'b', 10)");
// 下面三个都会使用GroupSortedIndex
// 也就是走queryGroupSorted_index_id_name_age索引
// group by后面字段的顺序是不重要的,谁先谁后都可以,所以下面两条sql会得到一样的结果
sql = "select id,name,count(id) from queryGroupSorted group by id,name";
executeQuery();
sql = "select id,name,count(id) from queryGroupSorted group by name,id";
executeQuery();
sql = "select id,name,age,count(id) from queryGroupSorted group by id,name,age having id<3";
executeQuery();
// 不会使用GroupSortedIndex,因为queryGroupSorted_index_id_name_age是按id, name, age的顺序,而不是id,age
sql = "select id,age,count(id) from queryGroupSorted group by id,age";
executeQuery();
// 不会使用GroupSortedIndex,
// group by字段必须是索引字段列表的前缀,这里是后缀了,少了id
sql = "select age,name,count(name) from queryGroupSorted group by age,name";
executeQuery();
// 同上
sql = "select name,age,count(name) from queryGroupSorted group by name,age";
executeQuery();
}
void queryQuick() throws Exception {
// 这样不行,因为id字段可以为null
// sql = "select count(id),min(id),max(id) from mytable";
// executeQuery();
// 如果先执行上面,那么由于缓存关系会直接使用前面的结果,所以并不执行Select.queryQuick()
stmt.executeUpdate("ALTER TABLE mytable ALTER COLUMN id SET NOT NULL");
sql = "select count(*),count(id),min(id),max(id) from mytable";
executeQuery();
}
void queryDistinct() throws Exception {
System.out.println();
stmt.executeUpdate("drop table IF EXISTS queryDistinct");
stmt.executeUpdate("create table IF NOT EXISTS queryDistinct(id int, name varchar(500))");
stmt.executeUpdate("ALTER TABLE queryDistinct ALTER COLUMN id SELECTIVITY 10");
stmt.executeUpdate("ALTER TABLE queryDistinct ALTER COLUMN name SELECTIVITY 10");
// stmt.executeUpdate("ALTER TABLE queryDistinct ADD CONSTRAINT NAME_UNIQUE UNIQUE(name,id)");
stmt.executeUpdate("create index IF NOT EXISTS queryDistinct_index on queryDistinct(name)");
// 不会选单列的唯一索引
// stmt.executeUpdate("create UNIQUE index IF NOT EXISTS queryDistinct_index on queryDistinct(name)");
// stmt.executeUpdate("insert into queryDistinct(id, name) values(" + 1
// + ", null)");
stmt.executeUpdate("insert into queryDistinct(id, name) values(" + 1 + ", 'a')");
stmt.executeUpdate("insert into queryDistinct(id, name) values(" + 2 + ", 'b')");
stmt.executeUpdate("insert into queryDistinct(id, name) values(" + 3 + ", 'a')");
stmt.executeUpdate("insert into queryDistinct(id, name) values(" + 4 + ", 'b')");
stmt.executeUpdate("insert into queryDistinct(id, name) values(" + 5 + ", 'c')");
sql = "select LIMIT 2 2 distinct name from queryDistinct";
sql = "select distinct name from queryDistinct";
executeQuery();
}
void getSortIndex() throws Exception {
System.out.println();
stmt.executeUpdate("drop table IF EXISTS getSortIndex");
stmt.executeUpdate("create table IF NOT EXISTS getSortIndex(id int, name varchar(500))");
stmt.executeUpdate("ALTER TABLE getSortIndex ALTER COLUMN id SELECTIVITY 10");
stmt.executeUpdate("ALTER TABLE getSortIndex ALTER COLUMN name SELECTIVITY 10");
// stmt.executeUpdate("ALTER TABLE getSortIndex ADD CONSTRAINT NAME_UNIQUE UNIQUE(name,id)");
stmt.executeUpdate("create index IF NOT EXISTS getSortIndex_id on getSortIndex(id)");
stmt.executeUpdate("create index IF NOT EXISTS getSortIndex_name_id on getSortIndex(name, id)");
stmt.executeUpdate("create UNIQUE index IF NOT EXISTS getSortIndex_name on getSortIndex(name DESC)");
// stmt.executeUpdate("insert into getSortIndex(id, name) values(" + 1 +
// ", null)");
stmt.executeUpdate("insert into getSortIndex(id, name) values(" + 1 + ", '" + 1 + "abcdef1234')");
stmt.executeUpdate("insert into getSortIndex(id, name) values(" + 2 + ", '" + 2 + "abcdef1234')");
stmt.executeUpdate("insert into getSortIndex(id, name) values(" + 3 + ", '" + 3 + "abcdef1234')");
stmt.executeUpdate("insert into getSortIndex(id, name) values(" + 4 + ", '" + 4 + "abcdef1234')");
stmt.executeUpdate("insert into getSortIndex(id, name) values(" + 5 + ", '" + 5 + "abcdef1234')");
sql = "select LIMIT 2 2 distinct name from getSortIndex";
// 测if (sortColumns[i].column != currentColumns[i].column)
sql = "select name from getSortIndex where id>1 order by name";
executeQuery();
// 测if (sortColumns[i].sortType != currentColumns[i].sortType)
// 如果把getSortIndex_name中的DESC去掉,swapIndex为false
// UNIQUE索引在org.h2.index.BaseIndex.getCostRangeIndex中算出的cost最小
sql = "select name from getSortIndex where name='1' order by name, id";
executeQuery();
sql = "select 3, name from getSortIndex order by name, 1";
executeQuery();
sql = "select 3, name from getSortIndex order by id";
executeQuery();
sql = "select id, name from getSortIndex order by _rowid_";
executeQuery();
}
void prepareOrder() throws Exception {
sql = "select id,name from mytable order by -1 DESC"; // 负数表示降序,再加DESC就表示降序的降序,实际就是升序
executeQuery();
sql = "select id,name from mytable order by -2 NULLS FIRST";
sql = "select id,name from mytable order by -2 NULLS LAST";
}
void prepare() throws Exception {
prepareOrder();
getSortIndex();
}
void queryWithoutCache() throws Exception {
// LIMIT 2 0 (实际上表示的是:OFFSET(2)、LIMIT(0))
sql = "select LIMIT 2 0 id,name from mytable";
executeQuery();
}
void queryFlat() throws Exception {
System.out.println();
// OFFSET(1)、LIMIT(2))
sql = "select LIMIT 1 2 id,age from mytable for update";
executeQuery();
}
void preparePlan() throws Exception {
sql = "explain select id,name from mytable where id>2 or age<50";
sql = "select id,name from mytable where id>2 and age<50";
executeQuery();
}
}