我应该在此“内部联接”语句中使用“带个案的选择”还是“其他”联合?

时间:2019-12-17 14:08:15

标签: sql

我如何执行一条SQL SELECT语句,该语句根据客户端的类型从客户端返回数据,但取决于类型,一个查询比其他查询具有更多的列,因此即使再放置一个查询,我也无法执行UNION命令语句的空列,因为它们将具有相同的列数。

关键字段P.PesTpP'Tipo'是客户端的类型,可以返回

我试图做这样的事情,但它返回此错误:

  

使用UNION,INTERSECT或EXCEPT运算符组合的所有查询必须   在目标列表中具有相等数量的表达式。

select P.PesCod 'Codigo', P.PesNom 'Nome Cliente', P.PesNomRes 'Nome Resumido', P.PesEMl 'E-mail', pt.pestel 'Telefone', e.PesEnd 'Endereco', e.PesEndNum 'Numero', e.PesEndCmp 'Logradouro', e.PesBai 'Bairro', e.PesCep 'CEP', e.PesCidCod 'IBGE', P.PesTpP 'Tipo',
j.jurCod 'CNPJ'

from PesCad P, cptcli c, PESTEL pt, PesEnd e,
PESJUR J
where P.PesCod = c.CliCod and P.PesCod = pt.PesCod and P.PesCod = e.PesCod and p.PesCod = j.JurCod and P.PesTpP = 'J'

UNION ALL

select P.PesCod 'Codigo', P.PesNom 'Nome Cliente', P.PesNomRes 'Nome Resumido', P.PesEMl 'E-mail', pt.pestel 'Telefone', e.PesEnd 'Endereco', e.PesEndNum 'Numero', e.PesEndCmp 'Logradouro', e.PesBai 'Bairro', e.PesCep 'CEP', e.PesCidCod 'IBGE', P.PesTpP 'Tipo', F.FisRGNum 'RG', f.FisCPF'CPF'

from PesCad P, cptcli c, PESTEL pt, PesEnd e,
PESFIS F

where P.PesCod = c.CliCod and P.PesCod = pt.PesCod and P.PesCod = e.PesCod and p.PesCod = F.FisCod and P.PesTpP = 'F'

2 个答案:

答案 0 :(得分:0)

鉴于您的查询,我认为这里不必使用UNION-您可以一次使用两个left join来获取所有所需信息:

select  p.PesCod 'Codigo',
        p.PesNom 'Nome Cliente',
        p.PesNomRes 'Nome Resumido',
        p.PesEMl 'E-mail',
        pt.pestel 'Telefone',
        e.PesEnd 'Endereco',
        e.PesEndNum 'Numero',
        e.PesEndCmp 'Logradouro',
        e.PesBai 'Bairro',
        e.PesCep 'CEP',
        e.PesCidCod 'IBGE',
        P.PesTpP 'Tipo',
        j.jurCod 'CNPJ',
        f.FisRGNum 'RG',
        f.FisCPF 'CPF'
from    PesCad p join cptcli c on P.PesCod = c.CliCod
        join PESTEL pt on P.PesCod = pt.PesCod
        join PesEnd e on P.PesCod = e.PesCod
        left join PESJUR j on p.PesCod = j.JurCod and P.PesTpP = 'J'
        left join PESFIS f on p.PesCod = F.FisCod and P.PesTpP = 'F'

如果PESJUR不是PesTpP,则J的列将为空;如果PESFIS不是PesTpP,则F的列将为空。

正如评论中所建议的,我还将您的join语法更新为显式语法,很多人都觉得这很容易理解

答案 1 :(得分:0)

考虑标准ANSI SQL的最佳做法:

  • Explicit JOIN用于多个表关系,而不是使用WHERE的隐式联接。即使两者都返回同等的性能,但显式联接可以说更具可读性和可维护性;
  • Optional AS keyword用于表示列或表的别名,以确保在执行查询期间重命名原始标识符。可以说,ASSELECT子句中更具可读性,但是某些IDE / CLI或JDBC / ODBC驱动程序可能在FROMJOIN子句中需要关键字和表别名。 / li>
  • Double quotes用于列别名而不是单引号(这不是ANSI,在某些RDBMS中可能会失败)。即使双引号也是可选的,并且仅在您要保留大小写组合,使用特殊字符(例如,空格,连字符)和关键字时才需要。记住旧的公理:

    [ S ]单引号用于[ S ]调整; [ D ]双引号用于[ D ]数据库标识符。

因此,如果您仍然想维护UNION查询方法,则只需添加NULL或常量(例如0'N/A')列即可SELECT表达式:

SELECT p.PesCod AS "Codigo", p.PesNom AS "Nome Cliente", p.PesNomRes AS "Nome Resumido", 
       p.PesEMl AS "E-mail", pt.pestel AS "Telefone", e.PesEnd AS "Endereco", 
       e.PesEndNum AS "Numero", e.PesEndCmp AS "Logradouro", e.PesBai AS "Bairro",
       e.PesCep AS "CEP", e.PesCidCod AS "IBGE", p.PesTpP AS "Tipo", 
       j.jurCod AS "CNPJ", NULL AS "RG", NULL AS "CPF"           --- UNMATCHED COLUMNS

FROM PesCad p
INNER JOIN cptcli c ON p.PesCod = c.CliCod
INNER JOIN PESTEL pt ON p.PesCod = pt.PesCod
INNER JOIN PesEnd e ON p.PesCod = e.PesCod
INNER JOIN PESJUR j ON p.PesCod = j.JurCod
WHERE p.PesTpP = 'J'

UNION ALL

SELECT p.PesCod AS "Codigo", p.PesNom AS "Nome Cliente", p.PesNomRes AS "Nome Resumido", 
       p.PesEMl AS "E-mail", pt.pestel AS "Telefone", e.PesEnd AS "Endereco", 
       e.PesEndNum AS "Numero", e.PesEndCmp AS "Logradouro", e.PesBai AS "Bairro",
       e.PesCep AS "CEP", e.PesCidCod AS "IBGE", p.PesTpP AS "Tipo", 
       NULL AS "CNPJ", f.FisRGNum AS "RG", f.FisCPF AS "CPF"     --- UNMATCHED COLUMNS

FROM PesCad p 
INNER JOIN cptcli c ON p.PesCod = c.CliCod
INNER JOIN PESTEL pt ON p.PesCod = pt.PesCod
INNER JOIN PesEnd e ON p.PesCod = e.PesCod
INNER JOIN PESFIS f ON p.PesCod = F.FisCod
WHERE p.PesTpP = 'F'