我如何执行一条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'
答案 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的最佳做法:
JOIN
用于多个表关系,而不是使用WHERE
的隐式联接。即使两者都返回同等的性能,但显式联接可以说更具可读性和可维护性; AS
keyword用于表示列或表的别名,以确保在执行查询期间重命名原始标识符。可以说,AS
在SELECT
子句中更具可读性,但是某些IDE / CLI或JDBC / ODBC驱动程序可能在FROM
和JOIN
子句中需要关键字和表别名。 / 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'