Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 仅当所有列都为空时才从其他表中选择_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

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

我使用以下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 = 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