Postgresql:select 与 func() 不同 *;
Postgresql : select distinct * from func() ;
---------------- PostgreSQL: ---------------------
drop table if exists test;
CREATE TABLE test
(
"Id" SERIAL NOT NULL,
"User" VARCHAR(64) NOT NULL,
"Name" VARCHAR(50) NOT NULL,
"DId" INTEGER NOT NULL,
PRIMARY KEY("User"));
----------------- CREATE TABLE ---------------------
truncate table test;
insert into test values
(1655,'1000000000','1000000000',6),
(844,'111','111',6),
(847,'114','114',6),
(849,'116','116',6),
(864,'131','131',6),
(884,'151','151',6),
(3242,'201919-11:29:3:340','sizhanerLD',6),
(3241,'201919-11:28:17:506','sizhanerZB',6),
(3240,'201919-11:27:37:15','sizhanerLD',6),
(3239,'201919-11:25:57:629','sizhanerZB',6);
----------------- INSERT DATA ----------------------
create TYPE "public"."BPI" as (
"Id" integer,
"DId" integer,
"User" VARCHAR(64),
"Name" VARCHAR(50)
);
---------------------------------CREATE TYPE --------------------------------------------------
--------------CREATE 3 FUNC()-----------------
CREATE OR REPLACE FUNCTION "QBP_1"()
RETURNS TABLE("Item" "BPI")
AS $$
declare
"MyCsr" refcursor;
"SqlStr" varchar(10240) := 'SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0';
BEGIN
raise notice 'SQL :%', "SqlStr";
open "MyCsr" for EXECUTE "SqlStr";
fetch "MyCsr" into "Item";
while FOUND loop
return next;
fetch "MyCsr" into "Item";
end loop;
close "MyCsr";
return ;
--select distinct * from "QBP_1"();
END;
$$ language plpgsql;
-----------------------------------------------------------------------
CREATE OR REPLACE FUNCTION "QBP_2"()
RETURNS TABLE("Id" integer,
"DId" integer,
"User" VARCHAR(64),
"Name" VARCHAR(64) )
AS $$
declare
"MyCsr" refcursor;
"SqlStr" varchar(10240) := 'SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0';
BEGIN
raise notice 'SQL :%', "SqlStr";
return query execute "SqlStr";
--select distinct * from "QBP_2"();
END;
$$ language plpgsql;
---------------------------------------------------------------
CREATE OR REPLACE FUNCTION "QBP_3"()
RETURNS SETOF "BPI"
AS $$
declare
"Item" "BPI";
"SqlStr" varchar(10240) := 'SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0';
BEGIN
raise notice 'SQL :%', "SqlStr";
for "Item" in execute "SqlStr" LOOP
return next "Item";
end LOOP;
--select distinct * from "QBP_3"();
END;
$$ language plpgsql;
SQL1: select distinct * from "QBP_1"();
SQL2: select distinct * from "QBP_2"();
SQL3: select distinct * from "QBP_3"();
SQL4: SELECT distinct "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0;
returning:
postgres=# select distinct * from "QBP_1"();
NOTICE: SQL :SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0
Id | DId | User | Name
------+-----+---------------------+------------
844 | 6 | 111 | 111
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
884 | 6 | 151 | 151
864 | 6 | 131 | 131
847 | 6 | 114 | 114
849 | 6 | 116 | 116
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
1655 | 6 | 1000000000 | 1000000000
(10 rows)
postgres=# select distinct * from "QBP_2"();
NOTICE: SQL :SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0
Id | DId | User | Name
------+-----+---------------------+------------
844 | 6 | 111 | 111
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
884 | 6 | 151 | 151
864 | 6 | 131 | 131
847 | 6 | 114 | 114
849 | 6 | 116 | 116
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
1655 | 6 | 1000000000 | 1000000000
(10 rows)
postgres=# select distinct * from "QBP_3"();
NOTICE: SQL :SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0
Id | DId | User | Name
------+-----+---------------------+------------
844 | 6 | 111 | 111
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
884 | 6 | 151 | 151
864 | 6 | 131 | 131
847 | 6 | 114 | 114
849 | 6 | 116 | 116
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
1655 | 6 | 1000000000 | 1000000000
(10 rows)
postgres=# SELECT distinct "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0;
Id | DId | User | Name
------+-----+---------------------+------------
1655 | 6 | 1000000000 | 1000000000
844 | 6 | 111 | 111
847 | 6 | 114 | 114
849 | 6 | 116 | 116
864 | 6 | 131 | 131
884 | 6 | 151 | 151
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
(10 rows)
如上代码所示。我为一个简单的测试创建了 3 个函数。但是好像SQL123returns命令错了。 (如果我删除 "distinct",返回的顺序是正确的)我是否错误地使用了 "distinct"?为什么?
最后,我为我糟糕的英语道歉。希望不影响阅读
关系数据库中的表表示关系。关系是一种特殊类型的(多)集合。集合没有顺序。因此 SQL 中的查询结果可以按任何顺序排列,除非 最外层 查询明确地使用 ORDER BY
子句对结果进行排序。
当然输出的结果是有物理顺序的。但重要的一点是,当缺少 ORDER BY
子句时,引擎可以按任何顺序 return 结果。在您的情况下,引擎可能会以 "good" 的方式处理函数的中间结果以进行重复数据删除(DISTINCT
),并且可以 "reorder" 元组(甚至可能每次都以另一个顺序发出查询)。
如果您想要一个有序的结果,请在最外层的查询中包含一个 ORDER BY
子句,例如
SELECT DISTINCT
*
FROM "QBP_1"()
ORDER BY "Name";
和其他功能的模拟。否则你不能期望某个顺序,即也没有 "wrong order" 然后。
附带说明:考虑不要使用这种始终需要引号的驼峰式标识符。这可能非常令人困惑。只使用不带引号(小写)的标识符可以省去一些麻烦。
---------------- PostgreSQL: ---------------------
drop table if exists test;
CREATE TABLE test
(
"Id" SERIAL NOT NULL,
"User" VARCHAR(64) NOT NULL,
"Name" VARCHAR(50) NOT NULL,
"DId" INTEGER NOT NULL,
PRIMARY KEY("User"));
----------------- CREATE TABLE ---------------------
truncate table test;
insert into test values
(1655,'1000000000','1000000000',6),
(844,'111','111',6),
(847,'114','114',6),
(849,'116','116',6),
(864,'131','131',6),
(884,'151','151',6),
(3242,'201919-11:29:3:340','sizhanerLD',6),
(3241,'201919-11:28:17:506','sizhanerZB',6),
(3240,'201919-11:27:37:15','sizhanerLD',6),
(3239,'201919-11:25:57:629','sizhanerZB',6);
----------------- INSERT DATA ----------------------
create TYPE "public"."BPI" as (
"Id" integer,
"DId" integer,
"User" VARCHAR(64),
"Name" VARCHAR(50)
);
---------------------------------CREATE TYPE --------------------------------------------------
--------------CREATE 3 FUNC()-----------------
CREATE OR REPLACE FUNCTION "QBP_1"()
RETURNS TABLE("Item" "BPI")
AS $$
declare
"MyCsr" refcursor;
"SqlStr" varchar(10240) := 'SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0';
BEGIN
raise notice 'SQL :%', "SqlStr";
open "MyCsr" for EXECUTE "SqlStr";
fetch "MyCsr" into "Item";
while FOUND loop
return next;
fetch "MyCsr" into "Item";
end loop;
close "MyCsr";
return ;
--select distinct * from "QBP_1"();
END;
$$ language plpgsql;
-----------------------------------------------------------------------
CREATE OR REPLACE FUNCTION "QBP_2"()
RETURNS TABLE("Id" integer,
"DId" integer,
"User" VARCHAR(64),
"Name" VARCHAR(64) )
AS $$
declare
"MyCsr" refcursor;
"SqlStr" varchar(10240) := 'SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0';
BEGIN
raise notice 'SQL :%', "SqlStr";
return query execute "SqlStr";
--select distinct * from "QBP_2"();
END;
$$ language plpgsql;
---------------------------------------------------------------
CREATE OR REPLACE FUNCTION "QBP_3"()
RETURNS SETOF "BPI"
AS $$
declare
"Item" "BPI";
"SqlStr" varchar(10240) := 'SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0';
BEGIN
raise notice 'SQL :%', "SqlStr";
for "Item" in execute "SqlStr" LOOP
return next "Item";
end LOOP;
--select distinct * from "QBP_3"();
END;
$$ language plpgsql;
SQL1: select distinct * from "QBP_1"();
SQL2: select distinct * from "QBP_2"();
SQL3: select distinct * from "QBP_3"();
SQL4: SELECT distinct "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0;
returning:
postgres=# select distinct * from "QBP_1"();
NOTICE: SQL :SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0
Id | DId | User | Name
------+-----+---------------------+------------
844 | 6 | 111 | 111
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
884 | 6 | 151 | 151
864 | 6 | 131 | 131
847 | 6 | 114 | 114
849 | 6 | 116 | 116
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
1655 | 6 | 1000000000 | 1000000000
(10 rows)
postgres=# select distinct * from "QBP_2"();
NOTICE: SQL :SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0
Id | DId | User | Name
------+-----+---------------------+------------
844 | 6 | 111 | 111
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
884 | 6 | 151 | 151
864 | 6 | 131 | 131
847 | 6 | 114 | 114
849 | 6 | 116 | 116
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
1655 | 6 | 1000000000 | 1000000000
(10 rows)
postgres=# select distinct * from "QBP_3"();
NOTICE: SQL :SELECT "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0
Id | DId | User | Name
------+-----+---------------------+------------
844 | 6 | 111 | 111
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
884 | 6 | 151 | 151
864 | 6 | 131 | 131
847 | 6 | 114 | 114
849 | 6 | 116 | 116
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
1655 | 6 | 1000000000 | 1000000000
(10 rows)
postgres=# SELECT distinct "Id", "DId", "User", "Name" from test ORDER BY "Name" ASC LIMIT 10 OFFSET 0;
Id | DId | User | Name
------+-----+---------------------+------------
1655 | 6 | 1000000000 | 1000000000
844 | 6 | 111 | 111
847 | 6 | 114 | 114
849 | 6 | 116 | 116
864 | 6 | 131 | 131
884 | 6 | 151 | 151
3242 | 6 | 201919-11:29:3:340 | sizhanerLD
3240 | 6 | 201919-11:27:37:15 | sizhanerLD
3241 | 6 | 201919-11:28:17:506 | sizhanerZB
3239 | 6 | 201919-11:25:57:629 | sizhanerZB
(10 rows)
如上代码所示。我为一个简单的测试创建了 3 个函数。但是好像SQL123returns命令错了。 (如果我删除 "distinct",返回的顺序是正确的)我是否错误地使用了 "distinct"?为什么?
最后,我为我糟糕的英语道歉。希望不影响阅读
关系数据库中的表表示关系。关系是一种特殊类型的(多)集合。集合没有顺序。因此 SQL 中的查询结果可以按任何顺序排列,除非 最外层 查询明确地使用 ORDER BY
子句对结果进行排序。
当然输出的结果是有物理顺序的。但重要的一点是,当缺少 ORDER BY
子句时,引擎可以按任何顺序 return 结果。在您的情况下,引擎可能会以 "good" 的方式处理函数的中间结果以进行重复数据删除(DISTINCT
),并且可以 "reorder" 元组(甚至可能每次都以另一个顺序发出查询)。
如果您想要一个有序的结果,请在最外层的查询中包含一个 ORDER BY
子句,例如
SELECT DISTINCT
*
FROM "QBP_1"()
ORDER BY "Name";
和其他功能的模拟。否则你不能期望某个顺序,即也没有 "wrong order" 然后。
附带说明:考虑不要使用这种始终需要引号的驼峰式标识符。这可能非常令人困惑。只使用不带引号(小写)的标识符可以省去一些麻烦。