Sql 仅当所有列都为空时才从其他表中选择
我使用以下SQL来获取员工的地址和其他信息Sql 仅当所有列都为空时才从其他表中选择,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我使用以下SQL来获取员工的地址和其他信息 SELECT emp_id, emp_name, @addr1 = ISNULL(ma.addr1, ba.addr1), @addr2 = ISNULL(ma.addr2, ba.addr2), @addr3 = ISNULL(ISNULL(ma.addr3, ba.addr3),''), @addr4 = ISNULL(ISNULL(ma.addr4, ba.addr4),''), @addr5
SELECT
emp_id,
emp_name,
@addr1 = ISNULL(ma.addr1, ba.addr1),
@addr2 = ISNULL(ma.addr2, ba.addr2),
@addr3 = ISNULL(ISNULL(ma.addr3, ba.addr3),''),
@addr4 = ISNULL(ISNULL(ma.addr4, ba.addr4),''),
@addr5 = ISNULL(ISNULL(ma.addr5, ba.addr5),''),
@postCode = ISNULL(ma.postcode, ba.postcode)
FROM dbo.employee e
INNER JOIN MainAddress ma ON ma.AddressId=e.AddressId
INNER JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
问题是,当主地址中的Addr1或其他字段为空时,它将采用辅助地址中的Addr3或其他字段,并显示这两个地址的混合。这是完全无效的
当主地址中的所有字段都为空(不可用)时,如何获取辅助地址?
注意:用户可以同时更新两个表,也可以只更新一个表 如果“不可用”表示main address
表中没有记录,则ma.AddressId
为空,因此,您可以对每个字段使用此条件:
CASE WHEN ma.AddressId IS NULL THEN ba.addr1 ELSE ma.addr1 END,
如果确实需要检查所有字段是否为空,则必须按如下方式更改案例条件:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
注意:如果有两种可能的情况,一种是根本没有行,另一种是行存在,但值都为空,则需要如下检查:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
正如评论中所说,我忘记告诉您必须使用左连接
,而不是内部连接
。如果不是,则如果在任何adress表中都没有员工的记录,则查询不会返回该员工
顺便说一句,如果您有一个地址表,并且有一个用于指定地址类型的鉴别器列:主地址或辅助地址,那么就容易多了。如果您这样做了,您只需从employee表中选择一个左联接
,并从address表中选择一个查询来获取TOP 1
。这将使您的应用程序开发人员在许多其他情况下变得更容易,例如查找一个您不知道是否是主地址的地址
更新:使用CTE
至于OP注释,有必要使用长表达式。为了使其更加清晰和易于维护,可以像这样使用CTE:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
如果“不可用”表示main address
表中没有记录,则ma.AddressId
为空,因此,您可以对每个字段使用此条件:
CASE WHEN ma.AddressId IS NULL THEN ba.addr1 ELSE ma.addr1 END,
如果确实需要检查所有字段是否为空,则必须按如下方式更改案例条件:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
注意:如果有两种可能的情况,一种是根本没有行,另一种是行存在,但值都为空,则需要如下检查:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
正如评论中所说,我忘记告诉您必须使用左连接
,而不是内部连接
。如果不是,则如果在任何adress表中都没有员工的记录,则查询不会返回该员工
顺便说一句,如果您有一个地址表,并且有一个用于指定地址类型的鉴别器列:主地址或辅助地址,那么就容易多了。如果您这样做了,您只需从employee表中选择一个左联接
,并从address表中选择一个查询来获取TOP 1
。这将使您的应用程序开发人员在许多其他情况下变得更容易,例如查找一个您不知道是否是主地址的地址
更新:使用CTE
至于OP注释,有必要使用长表达式。为了使其更加清晰和易于维护,可以像这样使用CTE:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
如果“不可用”表示main address
表中没有记录,则ma.AddressId
为空,因此,您可以对每个字段使用此条件:
CASE WHEN ma.AddressId IS NULL THEN ba.addr1 ELSE ma.addr1 END,
如果确实需要检查所有字段是否为空,则必须按如下方式更改案例条件:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
注意:如果有两种可能的情况,一种是根本没有行,另一种是行存在,但值都为空,则需要如下检查:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
正如评论中所说,我忘记告诉您必须使用左连接
,而不是内部连接
。如果不是,则如果在任何adress表中都没有员工的记录,则查询不会返回该员工
顺便说一句,如果您有一个地址表,并且有一个用于指定地址类型的鉴别器列:主地址或辅助地址,那么就容易多了。如果您这样做了,您只需从employee表中选择一个左联接
,并从address表中选择一个查询来获取TOP 1
。这将使您的应用程序开发人员在许多其他情况下变得更容易,例如查找一个您不知道是否是主地址的地址
更新:使用CTE
至于OP注释,有必要使用长表达式。为了使其更加清晰和易于维护,可以像这样使用CTE:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
如果“不可用”表示main address
表中没有记录,则ma.AddressId
为空,因此,您可以对每个字段使用此条件:
CASE WHEN ma.AddressId IS NULL THEN ba.addr1 ELSE ma.addr1 END,
如果确实需要检查所有字段是否为空,则必须按如下方式更改案例条件:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
注意:如果有两种可能的情况,一种是根本没有行,另一种是行存在,但值都为空,则需要如下检查:
CASE WHEN
ma.addres1 IS NULL AND ma.addres2 IS NULL ...
THEN ba.addr1 ELSE ma.addr1 END,
WITH ea AS -- the CTE, ea includes "employee + MainAdressExists column"
(
SELECT
*, -- select the required columns
-- plus an extra calculated column
CASE WHEN
ma.address1 IS NOT NULL
OR ma.address2 IS NOT NULL
-- add here all the column checks
THEN 1 ELSE 0 END AS MainAddressExists
FROM employee e
LEFT JOIN MainAddres ma ON ma.IdAddress = e.IdAdress
)
SELECT
-- choose the needed fields from ea
CASE WHEN P.MainAddressExists = 1 THEN ma.addres1 ELSE ba.address1 END
AS address1,
-- choose all the other address fields
FROM ea
LEFT JOIN MainAddress ma ON ma.AddressId=e.AddressId
LEFT JOIN SecondaryAddress ba ON ba.AddressId=e.AddressId
正如评论中所说,我忘记告诉您必须使用左连接
,而不是内部连接
。如果不是,则如果在任何adress表中都没有员工的记录,则查询不会返回该员工
顺便说一句,如果您有一个地址表,并且有一个用于指定地址类型的鉴别器列:主地址或辅助地址,那么就容易多了。如果您这样做了,您只需从employee表中选择一个左联接
,并从address表中选择一个查询来获取TOP 1
。这将使您的应用程序开发人员在许多其他情况下变得更容易,例如查找一个您不知道是否是主地址的地址
更新:使用CTE
至于OP