Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Problema com Generalização/Especializaç&#22


MatheusG10

Pergunta

Bom dia/tarde/noite, eu estou com um pequeno problema na minha especialização, na hora de consultar os registros, vou transpor o código abaixo:

create table Pessoa (
IDPessoa integer auto_increment unique,
constraint Pessoa_PK primary key (idpessoa)
);

create table Cliente (
IDCliente integer auto_increment,
Nome varchar(30),
CNPJ varchar(11),
Representante varchar(20),
constraint Cliente_PK primary key (idcliente),
constraint Pessoa_Cliente_FK foreign key (idcliente)
references Pessoa (idpessoa)
);

create table Funcionario (
IDFuncionario integer auto_increment,
Nome varchar(25),
Cargo varchar(20),
CPF integer(11),
constraint Funcionario_PK primary key (idfuncionario),
constraint Pessoa_Funcionario_FK foreign key (idfuncionario)
references Pessoa (idpessoa),
);

quando eu vou fazer uma busca de quantos funcionarios ou clientes estão cadastrados, eles se repetem na tabela e quando faço um select com as 3 tabelas a mesma ID de pessoa serve para uma id de funcionario e uma de cliente.

select idpessoa, nome from pessoa inner join cliente;

Link para o comentário
Compartilhar em outros sites

6 respostass a esta questão

Posts Recomendados

  • 0

Vamos arrumar esta casa:

Modifique as tabelas para este formato:

create table Pessoa (
    IDPessoa integer unsigned not null auto_increment unique,
    Nome varchar(50),
    TipoPessoa enum('C','F') not null, 
    constraint Pessoa_PK primary key (idpessoa)
);

create table Cliente (
    IDPessoa integer unsigned not null,
    CNPJ varchar(11),
    Representante varchar(20),
    constraint Cliente_PK primary key (IDPessoa),
    constraint Pessoa_Cliente_FK foreign key (IDPessoa)
        references Pessoa (IDPessoa)
);

 

create table Funcionario (
    IDPessoa integer unsigned not null,
    Cargo varchar(20),
    CPF integer(11),
    constraint Funcionario_PK primary key (IDPessoa),
    constraint Pessoa_Funcionario_FK foreign key (IDPessoa)
        references Pessoa (IDPessoa),
);
Com este arranjo você estabelecerá uma relação 1:1 entre pessoa e funcionário e uma relação 1:1 entre Pessoa e Cliente.

O atributo TipoPessoa em Pessoa definirá a qual tabela pertence a especialização desta generalização.

Link para o comentário
Compartilhar em outros sites

  • 0

<script type='text/javascript'>window.mod_pagespeed_start = Number(new Date());</script>

Vamos arrumar esta casa:
Modifique as tabelas para este formato:

create table Pessoa (
    IDPessoa integer unsigned not null auto_increment unique,
    Nome varchar(50),
    TipoPessoa enum('C','F') not null, 
    constraint Pessoa_PK primary key (idpessoa)
);

create table Cliente (
    IDPessoa integer unsigned not null,
    CNPJ varchar(11),
    Representante varchar(20),
    constraint Cliente_PK primary key (IDPessoa),
    constraint Pessoa_Cliente_FK foreign key (IDPessoa)
        references Pessoa (IDPessoa)
);

 

create table Funcionario (
    IDPessoa integer unsigned not null,
    Cargo varchar(20),
    CPF integer(11),
    constraint Funcionario_PK primary key (IDPessoa),
    constraint Pessoa_Funcionario_FK foreign key (IDPessoa)
        references Pessoa (IDPessoa),
);
Com este arranjo você estabelecerá uma relação 1:1 entre pessoa e funcionário e uma relação 1:1 entre Pessoa e Cliente.
O atributo TipoPessoa em Pessoa definirá a qual tabela pertence a especialização desta generalização.

VLW Denis!!!

no caso do unsigned, ele serviria para que? neste caso.

Link para o comentário
Compartilhar em outros sites

  • 0

... no caso do unsigned, ele serviria para que? neste caso

Reproduzindo o que diz o manual do MySQL

Um inteiro de tamanho normal. A faixa com sinal é de -2147483648 a 2147483647.

A faixa sem sinal é de 0 a 4294967295.

Como números auto_increment são inteiros positivos (sem sinal), que começam em 1, então o unsigned força para que esta faixa seja
Link para o comentário
Compartilhar em outros sites

  • 0

O problema foi resolvido, mas estou tendo problema na hora do select das 3 tabelas, eu ainda pensei se isso era possível devido a modelagem, pois ta retornando com dados repetidos ou retorna apenas cliente.

select t1.idpessoa, tipopessoa, nome, representante, cargo from pessoa t1
inner join cliente t2 on (t1.idpessoa = t2.idpessoa) inner join funcionario t3 on (t1.idpessoa = t3.idpessoa);

Link para o comentário
Compartilhar em outros sites

  • 0

Oi MatheusG10,

Em uma generalização o registro na tabela generalizada (Pessoa, no seu caso) possuirá UMA especialização apenas. OU este registro será um cliente OU será um funcionário.

Um outro ponto que estou observando em seu entendimento é o uso errado do INNER JOIN. Para o caso do select do post acima o correto seria usar o LEFT JOIN.

INNER JOIN é a INTERCESSÃO entre conjuntos. Traria somente os registros que correspondessem nas tabelas relacionadas.

Exemplo: Sejam os registros abaixo conforme suas tabelas:

A tabela generalizada Pessoa 2 registros sendo um deles Cliente e o outro Funcionário, tal como abaixo:

(1, "ZIPO PAPEIS", "C"), (2, "JOÃO", "F");

a tabela Cliente: (1, "11222333000144", "MATEUS") ;

e a tabela Funcionário: (2, "GERENTE", "11122233344");

O seu select

select t1.idpessoa, tipopessoa, nome, representante, cargo from pessoa t1
inner join cliente t2 on (t1.idpessoa = t2.idpessoa) inner join funcionario t3 on (t1.idpessoa = t3.idpessoa);

Sempre retornará um conjunto vazio.

Se você aplicar o select com LEFT JOIN

select t1.idpessoa, tipopessoa, nome, representante, cargo from pessoa t1
LEFT join cliente t2 on (t1.idpessoa = t2.idpessoa) LEFT join funcionario t3 on (t1.idpessoa = t3.idpessoa);
O resultado será:

"idpessoa" "tipopessoa" "nome" "representante" "cargo"

"1" "C" "ZIPO PAPEIS" "MATEUS" \N

"2" "F" "JOÃO" \N "GERENTE"

Onde /N é nulo

Link para o comentário
Compartilhar em outros sites

  • 0

<script type='text/javascript'>window.mod_pagespeed_start = Number(new Date());</script>

Oi MatheusG10,
Em uma generalização o registro na tabela generalizada (Pessoa, no seu caso) possuirá UMA especialização apenas. OU este registro será um cliente OU será um funcionário.
Um outro ponto que estou observando em seu entendimento é o uso errado do INNER JOIN. Para o caso do select do post acima o correto seria usar o LEFT JOIN.
INNER JOIN é a INTERCESSÃO entre conjuntos. Traria somente os registros que correspondessem nas tabelas relacionadas.
Exemplo: Sejam os registros abaixo conforme suas tabelas:
A tabela generalizada Pessoa 2 registros sendo um deles Cliente e o outro Funcionário, tal como abaixo:
(1, "ZIPO PAPEIS", "C"), (2, "JOÃO", "F");
a tabela Cliente: (1, "11222333000144", "MATEUS") ;
e a tabela Funcionário: (2, "GERENTE", "11122233344");
O seu select

select t1.idpessoa, tipopessoa, nome, representante, cargo from pessoa t1
inner join cliente t2 on (t1.idpessoa = t2.idpessoa) inner join funcionario t3 on (t1.idpessoa = t3.idpessoa);
Sempre retornará um conjunto vazio.
Se você aplicar o select com LEFT JOIN
select t1.idpessoa, tipopessoa, nome, representante, cargo from pessoa t1
LEFT join cliente t2 on (t1.idpessoa = t2.idpessoa) LEFT join funcionario t3 on (t1.idpessoa = t3.idpessoa);
O resultado será:

"idpessoa" "tipopessoa" "nome" "representante" "cargo"
"1" "C" "ZIPO PAPEIS" "MATEUS" \N
"2" "F" "JOÃO" \N "GERENTE"


Onde /N é nulo

Denis, agradeço muito!!!! resolveu aqui o problema.

Muito Obrigado,

Abraços.

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novos posts.


  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,5k
×
×
  • Criar Novo...