Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql >skeys((h1-h2)-'id':text)始终删除id,该id作为主键,显然在行之间总是不同的。_Postgresql_Postgresql 9.1_Duplicate Removal - Fatal编程技术网

Postgresql >skeys((h1-h2)-'id':text)始终删除id,该id作为主键,显然在行之间总是不同的。

Postgresql >skeys((h1-h2)-'id':text)始终删除id,该id作为主键,显然在行之间总是不同的。,postgresql,postgresql-9.1,duplicate-removal,Postgresql,Postgresql 9.1,Duplicate Removal,为此,您可以使用行的中间键/值表示,使用JSON函数,或者使用扩展名(现在仅具有历史意义)。JSON内置于每一个合理的最新版本的PostgreSQL中,而hstore必须安装在具有CREATE扩展的数据库中 演示: 让我们插入主键不同的两行和另一列(t3) 使用json的解决方案 首先,我们使用原始行号获取行的键/值表示,然后根据行的原始行号和 筛选出具有相同“值”列的值 h1-h2逐键计算差值,并将结果作为一组输出 结果: skeys ------- id t3 斯凯斯 -------

为此,您可以使用行的中间键/值表示,使用JSON函数,或者使用扩展名(现在仅具有历史意义)。JSON内置于每一个合理的最新版本的PostgreSQL中,而hstore必须安装在具有CREATE扩展的数据库中

演示:

让我们插入主键不同的两行和另一列(
t3

使用json的解决方案 首先,我们使用原始行号获取行的键/值表示,然后根据行的原始行号和 筛选出具有相同“值”列的值

h1-h2
逐键计算差值,并将结果作为一组输出

结果:

skeys ------- id t3 斯凯斯 ------- 身份证件 t3
选择列表可以使用
skeys((h1-h2)-'id'::text)
进行优化,以始终删除
id
,作为主键,它在行之间显然总是不同的。

您能否显示一个示例,例如3列和3家公司?始终只有2家公司需要比较。如果有更多的公司可能被复制,下次将对此进行比较。我没有线索,也不能举例说明。你能举例说明3栏和3家公司吗?通常只有2家公司可供比较。如果有更多的公司可能被复制,下次将对此进行比较。我没有线索,也不能举例说明。你为什么用光标?这不是禁止的,但也不是必需的:plpgsql可以处理这一点,而不需要额外的游标开销。@FrankHeikens,因为在标题的顶部,这是我知道的迭代列名的方式。如果您知道一种更好的方法,我将非常感谢您分享它。请使用行数据类型检查此示例:为什么使用游标?这不是禁止的,但也不是必需的:plpgsql可以处理这一点,而不需要额外的游标开销。@FrankHeikens,因为在标题的顶部,这是我知道的迭代列名的方式。如果你知道一个更好的方法,如果你能分享,我将不胜感激!就在现场。虽然我没有让“skeys((h1-h2)-“id”)部分工作。对于任何想删除
id
的人来说,它必须是
skeys((h1-h2)-“id”::text)
@Tao:谢谢。我合并了你的建议。还使用基于json的解决方案修改了答案,由于hstore有些过时,可能更合适。谢谢!就在现场。虽然我没有让“skeys((h1-h2)-“id”)部分工作。对于任何想删除
id
的人来说,它必须是
skeys((h1-h2)-“id”::text)
@Tao:谢谢。我合并了你的建议。还使用基于json的解决方案重新编写了答案,由于hstore有些过时,可能更合适。
SELECT showdifference('public','company','co_id',22,33)


CREATE OR REPLACE FUNCTION showdifference(p_schema text, p_tablename text,p_idcolumn text,p_firstid integer, p_secondid integer)
  RETURNS INTEGER AS
$BODY$ 
DECLARE
    l_diffcount INTEGER;
    l_column text;
    l_dupcount integer;
    column_cursor CURSOR FOR select column_name from information_schema.columns where table_name = p_tablename and table_schema = p_schema and column_name <> p_idcolumn;
BEGIN


    -- need error checking here, to ensure the table and schema exist and the columns exist

    -- Should also check that the records ids exist.

    -- Should also check that the column type of the id field is integer


    -- Set the number of differences to zero.

    l_diffcount := 0;

    -- use a cursor to iterate over the columns found in information_schema.columns
    -- open the cursor

    OPEN column_cursor;

    LOOP
        FETCH column_cursor INTO l_column;
        EXIT WHEN NOT FOUND;

        -- build a query to see if there is a difference between the columns. If there is raise a notice
        EXECUTE 'select count(distinct  ' || quote_ident(l_column) || ' ) from ' || quote_ident(p_schema) || '.' || quote_ident(p_tablename) || ' where ' || quote_ident(p_idcolumn) || ' in ('|| p_firstid || ',' || p_secondid ||')'
        INTO l_dupcount;



        IF l_dupcount > 1 THEN
        -- increment the counter
        l_diffcount := l_diffcount +1;
        RAISE NOTICE  '% has % differences', l_column, l_dupcount ; -- for "real" you might want to return a rowset and could do something here

        END IF;


    END LOOP;




    -- close the cursor
    CLOSE column_cursor;


    RETURN l_diffcount;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE STRICT
  COST 100;
CREATE TABLE table1 (id int primary key, t1 text, t2 text, t3 text);
INSERT INTO table1 VALUES 
 (1,'foo','bar','baz'),
 (2,'foo','bar','biz');
WITH rowcols AS (
  select rn,  key, value
  from (select row_number() over () as rn,
   row_to_json(table1.*) as r from table1) AS s
  cross join lateral json_each_text(s.r)
)
select r1.key from rowcols r1 join rowcols r2
on (r1.rn=r2.rn-1 and r1.key = r2.key)
where r1.value <> r2.value;
key ----- id t3
SELECT skeys(h1-h2) from 
  (select hstore(t.*) as h1 from table1 t where id=1) h1
 CROSS JOIN
  (select hstore(t.*) as h2 from table1 t where id=2) h2;
skeys ------- id t3