-1

在物业管理系统中,我根据买家的偏好来保存买家。假设一个人对超过 2 个小于 4 个的房屋感兴趣。所以我将其保存为 2,3,4。请参阅附件。

搜索时,假设有人搜索对拥有2个以上房屋的买家感兴趣,我应该如何编写select语句来检查卧室列。

如果有人搜索对拥有 2 间以上浴室的房屋感兴趣的买家;选择语句可能是什么?

在此处输入图像描述

4

3 回答 3

1

我仍然认为 min/max 是更好的表结构,但如果你不能改变它,试试这个。

首先,让我们提出一些基本规则。如果其中任何一个被违反,那么最终的答案将需要修改(并且可能会更复杂)。

  1. 如果字符串中包含+任何位置,则最大值为无穷大。
  2. +只能出现在字符串的末尾。
  3. 该列表将始终是逗号分隔的整数。
  4. 最小的数字将始终排在列表的首位。
  5. 最大的数字将始终位于列表的最后。

如果所有这些都是真的,那么经过大量的工作,我想我有一些你可以使用的东西。基本的想法是想出一对函数来从你的字符串中获取最小值/最大值。一旦有了这些功能,就可以在WHERE子句中使用它们。

对于初学者,请参阅此SQL Fiddle 。左侧的函数定义,一个示例查询,让您了解它们在右侧的工作原理。

CREATE FUNCTION dbo.list_min(@list_str AS VARCHAR(MAX))
  RETURNS INT
  WITH RETURNS NULL ON NULL INPUT
  AS BEGIN
    DECLARE @comma_index INT;
    SET @comma_index = CHARINDEX(',', @list_str);
    DECLARE @result INT;
    IF (0 < @comma_index)
      SET @result = CONVERT(INT, LEFT(@list_str, @comma_index - 1));
    ELSE
      SET @result = CONVERT(INT, REPLACE(@list_str, '+', ''));
    RETURN @result;
  END;

CREATE FUNCTION dbo.list_max(@list_str AS VARCHAR(MAX))
  RETURNS INT
  WITH RETURNS NULL ON NULL INPUT
  AS BEGIN
    IF (@list_str LIKE '%+')
      RETURN 2147483647; -- Max INT
    DECLARE @comma_index INT;
    SET @comma_index = CHARINDEX(',', REVERSE(@list_str));
    DECLARE @result INT;
    IF (0 < @comma_index)
      SET @result = CONVERT(INT, RIGHT(@list_str, @comma_index - 1));
    ELSE
      SET @result = CONVERT(INT, @list_str);
    RETURN @result;
  END;

(如果有人能想出摆脱那个荒谬result变量的方法,告诉我。在将 return 放入IF/时,我收到关于最后一条语句“must be a return statement”的错误ELSE,我无法得到CASE语法工作。)

有了这些,您可以进行如下查询:

SELECT *
FROM stuff
WHERE dbo.list_min(carspace) <= 2 AND 2 <= dbo.list_max(carspace)

这只会选择你的第二行。(此查询的SQL Fiddle。)

您可能会发现有用的第三个功能是为您提供列表中的最大值但忽略+. 为此,它本质上是list_max函数,但没有IF检查+. 要获得该功能,您可能只想+从 中删除检查list_max,并创建另一个函数来检查并在没有 时+调用。list_max+

我不确定这里的性能特征。我想他们不是很好。如果您有大量数据要搜索,您可能需要考虑一些基于函数的索引。

祝你好运。希望这可以帮助。

于 2013-08-08T09:01:33.500 回答
1

<=存储 min 和 max 然后使用and查询不是更有意义>=吗?

于 2013-08-07T05:37:09.587 回答
0

您的桌子设计不是最佳的。您可以简单地将卧室数量存储为整数。在这种情况下,您将只看到 4 而不是“1,2,3,4”。

不过,要回答特定问题,您可以使用替换技巧来计算列中逗号的数量,如下所示:

SELECT * FROM myTable WHERE LEN(col) - LEN(REPLACE(col, ',','')) >= someNumber

于 2013-08-07T05:39:57.840 回答