子选择条件

时间:2016-01-07 21:04:56

标签: sql sql-server tsql sql-server-2012

我有一个子查询,可以获取提交投诉的人的地址。此人可以拥有多个地址。我们过去只选择“OR”类型的地址,这样可以得到一个干净的子查询...

(SELECT TOP 1 Address 
 FROM Address WHERE NameID = PersNameID AND AddressTypeCode = 'OR') AS ComplainantAddress

现在,输入地址的方式,它们可能有也可能没有“OR”类型的地址。它们可能只有“ML”类型或“BU”和“ML”类型的地址。

我需要获取为该人填充的第一个地址,以指定的顺序查找(按类型)。我可以做一个巨大的CASE声明,但这是最好的方法吗?或者我应该使用ORDER By更改为JOIN并获取第一个非空值?

寻找建议。

2 个答案:

答案 0 :(得分:6)

您不必使用CASE,但您必须做类似的事情。以下是使用CHARINDEX()

的技巧
(SELECT TOP 1 Address 
 FROM Address
 WHERE NameID = PersNameID 
 ORDER BY CHARINDEX(AddressTypeCode, 'OR,ML,BU')
) 

如果您有其他代码而不想先使用它们,那么:

(SELECT TOP 1 Address 
 FROM Address
 WHERE NameID = PersNameID 
 ORDER BY (CASE WHEN AddressTypeCode IN ('OR', 'ML', 'BU')
                THEN 1 ELSE 2
           END),
          CHARINDEX(AddressTypeCode, 'OR,ML,BU')
) 

编辑:

我应该注意到有更多深奥的方法可以做同样的事情:

(SELECT TOP 1 Address 
 FROM Address LEFT OUTER JOIN
      (VALUES ('OR', 1), ('ML', 2), ('BU', 3)
      ) codes(code, priority)
      ON Address.AddressTypeCode = codes.code
 WHERE NameID = PersNameID 
 ORDER BY COALESCE(codes.priority, 999999)
) 

这更像SQL-Server'。字符串操作几乎适用于任何数据库(在函数名称中都有变化)。

答案 1 :(得分:2)

如果您要为您的地址设置优先级,那么我建议您在数据库中捕获该地址。因此,假设您的AddressTypes表格中有ComplaintPriority列,则可以执行以下操作:

SELECT TOP 1
    A.Address
FROM
    Address A
INNER JOIN AddressTypes T ON T.AddressTypeCode = A.AddressTypeCode
WHERE
    A.NameID = PersNameID  -- Not sure where this is coming from
ORDER BY
    T.ComplaintPriority