Mysql select multiple columns from the same table with conditions

Asked

Viewed 2,463 times

1

I need to select some data from a single table depending on the type of user, for example, a Personal user will have the field RG and PIS while a user will have the field State registration and fancy name.

I can run a query similar to LEFT JOIN, but all fields are selected, differing only from having the field filled or null, according to the type of user. What I want is to select the fields only when the type is corresponding, eg.:

  • Type 1 or 2: Selects common fields;
  • Type = 1: Selects Natural Person data (completed or not);
  • Type = 2: Selects Legal Entity data (completed or not);

To query that I currently have would be more or less like this:

SELECT
    a.campo_a, a.campo_b, a.campo_c,

    -- Tipo 1
    b.campo_d, b.campo_e, --pode ter mais campos aqui

    -- Tipo 2
    c.campo_f, c.campo_g --pode ter mais campos aqui

FROM tabela AS a
    LEFT JOIN tabela AS b ON a.tipo = 1
    LEFT JOIN tabela AS c ON a.tipo = 2
WHERE a.id = :id

However, if I am selecting type 1, I still see the fields campo_f and campo_g, I wish they wouldn’t even show up, it’s possible?

  • having as example individual/legal person, in the same table you have 2 columns, one for CPF and the other for correct CNPJ ? It has many columns so ?

2 answers

2


1-Option: Union (only if same data type)

SELECT
    nome, 
    cpf, 
    rg
FROM pessoas where tipo = 1

UNION 

SELECT
    razao,
    cnpj,
    ie
FROM pessoas where tipo = 2;

Option: Coalesce (if fields are null when of another type)

SELECT
Coalesce(nome,razao) as nome,
Coalesce(cpf,cnpj) as documento,
Coalesce(rg,ie) as registro
FROM pessoas;

3-Option: Change the database (I would do so)

Column nome: would share data of social reason for legal entities, and name of natural persons.

Column documento: share cnpj data for legal entities, and Cpf for natural persons.

Column apelido: would share fancy name for legal persons, and nickname for natural persons.

Then the SQL gets clean, no problem at all.

Select
  nome,
  apelido,
  documento,
  ...
From pessoas;

Edit:

Whereas will load PF and PJ at different times, ie, should not come in the same SELECT, would by programming.

string sql;
if (pf)
 sql = "select nome, cpf, ... from pessoas;";
else
 sql = "select razao, cnpj, ... from pessoas";

...executa sql;

however, this way you may have problems filling your variables by column name.

  • Option 1 works partially because depending on the data types, the return is false. Option 2 and option 3 do not apply to my current structure. Answering your question in the comment: the table focuses on PF client, with many fields related to it, such as rg, PIS, etc.. Some fields (2-4) are related to PJ. What I want to avoid is precisely the unnecessary loading in the case of PJ. But I think I will LEFT JOIN and deal with PHP itself, I see that with sql I will not get the desired result.

  • on the subject of Union data types, you can try to convert them if possible. And if, there are only 2-4 legal persons fields, I would consider changing the table to option 3 that I posted. I would not use this option of LEFT JOIN, it seems unnecessary. There is also the option of an IFF function(bool, true, false)

  • Yeah, but the problem isn’t that much. I worry more about the fact that I have to load 10-15 more fields and null when I am loading a PJ client, because there is a difference. Most of the fields refer to PF client. In case of using option 3, I already do something shared, I have fields like nome-razao and cpf-cnpj, which already share the equivalent information. Perhaps even table segmentation, e.g..: cliente, cliente_pf and cliente_pj

  • well, I’m thinking it should be to load pf and pj in the same select, if it’s for when different types, different commands, even better in php you make a conditional

  • Yeah, I just don’t know if I load all the fields and then remove the ones that are null, or I check the type to execute a select or another. This query is only run for loading from a single client and not from an entire list, so the impact on performance will be no problem.

  • then you have to see how you display this data, if it is dynamic, would use this condition within php

  • Yes yes, but thanks for the tips! Now I understood why UNION didn’t work before (I had tested with him).

Show 2 more comments

0

CASE , something like that

select (case when tipo = 1 then cpf
             when tipo = 2 then cnpj
             else null end) cpf_cnpj, 
... 
  • the problem is that with CASE I could not use more than one field, unless create multiple cases, which would be impracticable. Then it would be better to keep the left Join.

  • Rovann’s UNION option is also viable;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.