AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 222064
Accepted
Sig
Sig
Asked: 2018-11-08 23:52:24 +0800 CST2018-11-08 23:52:24 +0800 CST 2018-11-08 23:52:24 +0800 CST

Transmitindo uma matriz de textos para uma matriz de UUIDs

  • 772

Como posso converter uma matriz de texts em uma matriz de UUIDs?

Eu preciso fazer um joinentre duas tabelas: userse projects.

A userstabela tem um campo de matriz chamado project_idscontendo os IDs do projeto como texto.

A projectstabela tinha um campo UUID chamado id.

Minha ideia inicial era uma consulta parecida com:

SELECT * FROM projects
JOIN users ON
projects.id = ANY(users.project_ids)

Mas isso não funciona, pois users.project_idsnão são UUIDs, então tentei:

projects.id = ANY(users.project_ids::uuid[])

e até mesmo:

projects.id = ANY(ARRAY[users.project_ids]::uuid[])

mas nenhum deles funciona:

ERROR: invalid input syntax for type uuid: ""

ATUALIZAR

@a_horse_with_no_name está definitivamente certo. A melhor opção deve ser usar uma matriz de UUIDs.

A questão agora é como posso alterar uma matriz de textem uma matriz de uuid?

A userstabela está atualmente vazia (0 registros).

eu tentei

ALTER TABLE "users" ALTER COLUMN "project_ids" SET DATA TYPE UUID USING "project_ids"::uuid[];

que gera

ERRO: o resultado da cláusula USING para a coluna "product_ids" não pode ser convertido automaticamente para o tipo uuid DICA: Talvez seja necessário adicionar um cast explícito.

ALTER TABLE "users" ALTER COLUMN "product_ids" SET DATA TYPE UUID USING "product_ids"::UUID;

eu também tentei

ALTER TABLE "users" ALTER COLUMN "project_ids" SET DATA TYPE UUID[] USING "project_ids"::uuid[];

que gera

ERRO: o padrão para a coluna "project_ids" não pode ser convertido automaticamente para digitar uuid[]

A coluna é definida como uma matriz vazia como padrão.

Estou executando o PG versão 10.4 e project_idsatualmente é text[] nullable.

postgresql join
  • 3 3 respostas
  • 32271 Views

3 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2018-11-09T07:37:47+08:002018-11-09T07:37:47+08:00

    Como já foi comentado, a coluna project_idsdeveria ser uuid[], o que evitaria o problema. Também seria mais eficiente.

    Para alterar (sem dados ilegais na coluna como você afirmou):

    ALTER TABLE users ALTER COLUMN project_ids DROP DEFAULT;
    
    ALTER TABLE users
    ALTER COLUMN project_ids SET DATA TYPE uuid[] USING project_ids::uuid[];
    

    Você tinha uuidem vez de uuid[]por engano.

    E isto:

    ERROR: default for column "product_ids" cannot be cast automatically to type uuid[]
    

    .. significa que você tem um valor padrão definido para a coluna. Essa expressão não pode ser transformada automaticamente. Remova-o antes de alterar o tipo. Você pode adicionar um novo DEFAULTmais tarde.

    Corrigir o problema original

    A correção eficiente em sua situação original é remover strings vazias do array antes da conversão (requer Postgres 9.3+):array_remove()

    SELECT *
    FROM   users    u
    JOIN   projects p ON p.id = ANY(array_remove(u.project_ids, '')::uuid[]);
    

    ... depois de investigar por que pode haver picadas vazias nessa text[]coluna.

    Relacionado:

    • Excluir elemento do array por índice
    • A pesquisa de índice seria visivelmente mais rápida com char vs varchar quando todos os valores são 36 caracteres

    Pontos finos

    • O [INNER] JOINem sua consulta remove usuários sem projetos válidos projects_idsdo resultado. Normalmente, você também deseja mantê - los: use LEFT [OUTER] JOINem vez disso (com usersprimeiro).

    • As JOINdobras duplicam as entradas de qualquer maneira, o que pode ou não ser o desejado. Se você quiser representar entradas duplicadas, desvincule antes da junção.

    E se o seu objetivo é simplesmente resolver o array de IDs para um array de nomes de projetos, você também vai querer preservar a ordem original dos elementos do array:

    SELECT *
    FROM   users u
    LEFT   JOIN LATERAL (
       SELECT ARRAY(
          SELECT project_name  -- use the actual column(s) of your case
          FROM   unnest (array_remove(u.project_ids, '')::uuid[]) WITH ORDINALITY AS p(id, ord)
          JOIN   projects USING (id)
          ORDER  BY ord
          )
       ) p(projects) ON true;
    

    db<>fiddle aqui (vagamente baseado no violino de McNets )

    Relacionado:

    • Como preservar a ordem original dos elementos em uma matriz não aninhada?
    • 4
  2. McNets
    2018-11-09T00:23:32+08:002018-11-09T00:23:32+08:00
    create table users (user_id int, projects text[]);
    
    insert into users values
    (1, (array['a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
               'b0eebc99-9c0b-4ef8-bb6d-cbb9bd380a11'])::text[]);
    
    insert into users values
    (2, (array['a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
               'b0eebc99-9c0b-4ef8-bb6d-cbb9bd380a11',
               'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'])::text[]);
    
    insert into users values
    (3, (array['f0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11',
               '',
               'e0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'])::text[]);
    
    create table projects (project_id uuid);
    
    insert into projects values
    ('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid),
    ('d0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid),
    ('e0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid);
    

    Como a_horse_with_no_name apontou, ele falha se algum elemento do array não tiver valor. Não pode ser convertido.

    select user_id, project_id
    from   projects
    join   users
    on     project_id = any(projects::uuid[])
    
    ERRO: sintaxe de entrada inválida para o tipo uuid: ""
    
    

    No entanto, você pode tentar converter project_idcomo texto desta maneira:

    select user_id, project_id
    from   projects
    join   users
    on     project_id::text = any(projects);
    
    user_id | ID_do_projeto                          
    ------: | :-----------------------------------
          1 | a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
          2 | a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
          3 | e0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
    

    db<>fique aqui

    Ou você pode expandir o array (unnest) e evitar valores vazios/nulos:

    with usr as
    (
        select user_id, unnest(projects) as project_id
        from   users
    )
    select user_id, projects.project_id
    from   projects
    join   usr
    on     coalesce(usr.project_id, '') <> ''
    and    usr.project_id::uuid = projects.project_id;
    
    user_id | ID_do_projeto                          
    ------: | :-----------------------------------
          2 | a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
          1 | a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
          3 | e0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
    

    db<>fique aqui

    • 3
  3. Paul A Jungwirth
    2022-08-26T09:00:25+08:002022-08-26T09:00:25+08:00

    Como posso converter uma matriz de textos em uma matriz de UUIDs?

    No seu caso, concordo com os outros que project_idsdeveriam ser apenas uuid[]para começar. Mas para o problema mais geral, você pode definir um elenco para lidar com isso automaticamente:

    CREATE CAST (text[] AS uuid[]) WITH INOUT AS ASSIGNMENT;

    Isso converterá automaticamente as coisas para você quando você fizer um INSERTetc. Você também pode dizer AS IMPLICITpara cobrir mais casos, embora isso possa causar ambiguidades no tempo de análise.

    • 0

relate perguntas

  • Qual é a diferença entre um INNER JOIN e um OUTER JOIN?

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Como é a saída de uma instrução JOIN?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve