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 / 202254
Accepted
guettli
guettli
Asked: 2018-03-26 23:57:55 +0800 CST2018-03-26 23:57:55 +0800 CST 2018-03-26 23:57:55 +0800 CST

Obter membros de um determinado grupo do relacionamento N:M

  • 772

Eu tenho essa relação N:M:

CREATE TABLE auth_user (
    id integer NOT NULL PRIMARY KEY,
    username character varying(150) NOT NULL UNIQUE
);

CREATE TABLE auth_group (
    id integer NOT NULL PRIMARY KEY,
    name character varying(80) NOT NULL UNIQUE
);

CREATE TABLE auth_user_groups (
    id integer NOT NULL PRIMARY KEY,
    user_id integer REFERENCES auth_user(id) NOT NULL,
    group_id integer REFERENCES auth_group(id) NOT NULL,
    CONSTRAINT user_groups UNIQUE(user_id, group_id)
);

INSERT INTO auth_user VALUES (1, 'user1');
INSERT INTO auth_user VALUES (2, 'user2');
INSERT INTO auth_group VALUES (1, 'group1');
INSERT INTO auth_group VALUES (2, 'group2');
INSERT INTO auth_user_groups VALUES (1, 1, 1);
INSERT INTO auth_user_groups VALUES (2, 2, 1);
INSERT INTO auth_user_groups VALUES (3, 2, 2);

Como selecionar todos os nomes de usuário que estão no grupo 'group1'?

Eu uso o PostgreSQL, mas o SQL que funciona em todos os lugares é o preferido.

postgresql join
  • 5 5 respostas
  • 367 Views

5 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2018-03-29T06:11:28+08:002018-03-29T06:11:28+08:00

    Essa EXISTSconsulta retorna usuários únicos, independentemente de haver entradas duplicadas em auth_user_groups.

    SELECT *
    FROM   auth_user u
    WHERE  EXISTS (
       SELECT 1
       FROM   auth_user_groups
       WHERE  user_id = u.id
       AND    group_id = (SELECT id FROM auth_group WHERE name = 'group1')
       );
    

    Normalmente rápido também.

    Notas

    Para Postgres - que você parece estar usando.

    A sequência de colunas de índice é importante. Você definiu UNIQUE(user_id, group_id), que é implementado com um índice exclusivo correspondente. Para sua consulta específica, um índice em (group_id, user_id)seria preferível.

    Você pode alternar as colunas da UNIQUErestrição ou criar um índice adicional (opcionalmente exclusivo) com as colunas invertidas se precisar de ambos (o que é o caso comum). Relacionado:

    • Um índice composto também é bom para consultas no primeiro campo?

    Também esteja ciente de que as colunas incluídas em uma UNIQUErestrição ainda podem ser NULL. (Ao contrário de uma PRIMARY KEYrestrição que faz com que todas as colunas de membros sejam NOT NULLautomaticamente!) Você normalmente deseja user_ide também group_ido auth_user_groupsseja NOT NULL. Relacionado:

    • Como implementar um relacionamento muitos-para-muitos no PostgreSQL?
    • 8
  2. a_horse_with_no_name
    2018-03-27T00:19:49+08:002018-03-27T00:19:49+08:00

    Algo assim:

    select *
    from auth_user
    where id in (select aug.user_id
                 from auth_group ag
                   join auth_user_groups aug on aug.group_id = ag.id
                 where ag.name = 'group1');
    
    • 6
  3. jean
    2018-03-29T05:16:31+08:002018-03-29T05:16:31+08:00

    A_horse_with_no_name postou uma boa resposta, na verdade essa era minha opção principal (merecia um upvote =))

    Você também pode fazer isso da maneira usual:

    select au.*
    from dbo.auth_user au
    join dbo.auth_user_groups aug on aug.[user_id] = au.id
    join dbo.auth_group ag on ag.id = aug.group_id
    where ag.[name] = 'group1'
    

    Mas observe que, se você tiver mais de um grupo com o mesmo nome e usuários em grupos homônimos, obterá linhas duplicadas:

    INSERT INTO auth_group VALUES (3, 'group1');
    INSERT INTO auth_user_groups VALUES (1, 1, 3);
    

    Nesse caso, você deve usar um distinto:

    select distinct au.*
    from dbo.auth_user au
    join dbo.auth_user_groups aug on aug.[user_id] = au.id
    join dbo.auth_group ag on ag.id = aug.group_id
    where ag.[name] = 'group1'
    

    Observação A resposta A_Horse ainda funciona nesse caso.

    • 2
  4. wBob
    2018-03-29T15:09:34+08:002018-03-29T15:09:34+08:00

    A partir do SQL Server 2017 e do Azure SQL DB, você pode usar os novos recursos do banco de dados gráfico e a nova cláusula MATCH para responder a consultas como esta, por exemplo

    SELECT FORMATMESSAGE ( 'User %s (%i) is in group %s.', [user].userName, [user].userId, [group].groupName ) msg
    FROM dbo.users [user], dbo.hasGroup hasGroup, dbo.groups [group]
    WHERE [group].groupName = 'group1'
      AND MATCH ( [user]-(hasGroup)->[group] );
    

    Meus resultados:

    Meus resultados

    Roteiro completo disponível aqui .

    • 2
  5. guettli
    2018-04-05T23:11:18+08:002018-04-05T23:11:18+08:00
    select username from auth_user, auth_user_groups, auth_group where 
      auth_group.name='group1' and 
      auth_user_groups.group_id=auth_group.id and
      auth_user.id=auth_user_groups.user_id;
    
    • 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