2

我正在搜索我想保持自然顺序以保持排名的地方。这是我的代码查询:

SELECT buyer_id, first, last, ALLTRIM(address) AS address1, city, state FROM BUYERMAST.DBF WHERE first = '{0}' AND last = '{1}' UNION 
SELECT buyer_id, first, last, ALLTRIM(address) AS address1, city, state FROM BUYERMAST.DBF WHERE phone = '{6}' UNION 
SELECT buyer_id, first, last, ALLTRIM(address) AS address1, city, state FROM BUYERMAST.DBF WHERE first LIKE '{0}' AND last LIKE '{1}' UNION 
SELECT buyer_id, first, last, ALLTRIM(address) AS address1, city, state FROM BUYERMAST.DBF WHERE address LIKE '{2}' AND city LIKE '{3}' UNION 
SELECT buyer_id, first, last, ALLTRIM(address) AS address1, city, state FROM BUYERMAST.DBF WHERE first = '{0}' OR last = '{1}' OR address = '{2}' OR city = '{3}' OR state = '{4}' OR zip = '{5}' OR phone = '{6}' or email = '{7}'"

联合中的第一个选择返回一个完全匹配,而最后一个选择返回一个非常普遍的匹配。问题是结果总是按buyer_id 排序返回。我无法更改现有的表/索引,并且我看到有几个索引,buyer_id 是第一个。如果可能,我想“禁用”索引顺序,以便首先返回第一个选择的结果,随后的选择实际上附加到前一个。这可能吗?

PS默认情况下,联合是不同的,如果我为每个选择添加一个“排名”列并按此排序,它将留下重复的结果,因为每个选择查询之间的排名列是不同的。

4

2 回答 2

1

在一个查询中具有所有限定符的 SINGLE 查询怎么样,但附加列作为它们限定的标志...由于您的最后一个联合具有全面的“或”值,只需将其用作 WHERE,但具体标准为标记它是如何合格的,然后您可以每人保留一个条目,但将其标记为“howeverMatched”以进行分析。

SELECT 
      buyer_id, 
      first, 
      last, 
      address AS address1, 
      city, 
      state,
      ( first = '{0}' AND last = '{1}' ) as ExactNameMatch,
      ( phone = '{6}' ) as PhoneMatch,
      ( LIKE( first, '{0}' ) AND LIKE( last, '{1}' )) as LikeNameMatch,
      ( LIKE( address, '{2}' ) AND LIKE( city, '{3}' )) as LikeAddressMatch
   FROM 
      BuyerMast
   WHERE 
         first = '{0}' 
      OR last = '{1}' 
      OR address = '{2}' 
      OR city = '{3}' 
      OR state = '{4}' 
      OR zip = '{5}' 
      OR phone = '{6}' 
      OR email = '{7}'
      OR ( first LIKE '{0}' AND last LIKE '{1}' )
      OR ( address LIKE '{2}' AND city LIKE '{3}' )

它不喜欢名称匹配限定符中的“LIKE”......所以 LikeNameMatch 和 LikeAddressMatch 是罪魁祸首......但是,VFP 确实有一个功能,所以我改变了它们

from   first LIKE '{0}'
to     LIKE( first, '{0}' )

与其他类似。

于 2012-04-18T10:56:34.163 回答
0

我不相信有可能直接做到这一点。目标是在没有 ORDER BY 子句的情况下对结果进行某种隐含顺序,问题是关系没有特定顺序。因此,除非查询依赖于数据库引擎的实现特定行为,否则您可能无法直接到达那里。

aUNION ALL可能会保留原始订单,尽管我不知道这是有保证的。如果是这样(或者即使不是,您也可以使用 OP 中提到的排名想法来执行 ORDER BY),然后您可以在查询后“手动”删除重复项。

另一种可能导致查询极其丑陋并且可能难以优化的可能性是再次使用 UNION ALL(或排名想法)来获取每个条件的结果,但将NOT先前条件的每个后续条件添加到每个后续条件中。换句话说,让每个单独的 SELECT 只选择它专门添加到最终结果的行:

SELECT ... WHERE condition1 UNION ALL
SELECT ... WHERE condition2 and NOT (condition1) UNION ALL
SELECT ... WHERE condition3 and NOT(condition1) and NOT (condition2)
etc. and on into a very ugly query

请注意,在上面的示例中,如果 UNION ALL 确实不保留顺序,您可以在每个选择中添加一个排名值,然后按该值对最终结果进行排序(查询本身将具有内置的唯一性,所有not(condition)条款。

于 2012-04-18T00:18:27.757 回答