3

我是 SQL 新手,所以我需要你的帮助来查询。基本上我有一个邮政编码数据库,我想在选定的邮政编码之前获取 3 个项目,之后获取 3 个项目。我提出的查询非常糟糕......

WITH numberedlogtable AS
(
SELECT *
 FROM dbo.US
)

SELECT *
FROM numberedlogtable
WHERE ZipCode IN (SELECT ZipCode+i
             FROM numberedlogtable
             CROSS JOIN (SELECT -1 AS i UNION ALL SELECT 0 UNION ALL SELECT 1) n
             WHERE ZipCode='91803')

我从某个地方拿起了一个示例查询,并成功地将其转换为我使用。唯一的问题是此查询返回当前项目和下一个项目。相反,它应该返回前 3 个项目、当前项目和下三个项目。

4

3 回答 3

5

使用WITH产生编号序列的公用表表达式(部分):

WITH NumberedZipCodes AS
(SELECT SELECT ROW_NUMBER() OVER (ORDER BY ZipCode) AS RowNumber, *
FROM ZipCodes)

SELECT * From NumberedZipCodes
WHERE RowNumber BETWEEN
(SELECT RowNumber FROM NumberedZipCodes WHERE ZipCode=91803) - 3
AND (SELECT RowNumber FROM NumberedPerson WHERE ZipCode=91803) + 3

通常在 SQL 中没有匹配中的上一个或下一个项目这样的概念。实际上,除非指定 order by 子句,否则行将按 sql 引擎认为合适的任何顺序返回。要进行这样的查询,必须应用订单并生成索引号。这是在 NumberedZipCodes 中完成的。第二部分只是从中获取数据的查询。

要使查询高效运行,请确保ZipCode列上有索引。

于 2012-05-06T07:22:57.573 回答
4

“之前”和“之后”仅在排序的上下文中才有意义。假设您希望按邮政编码订购,选择所需的邮政编码和 2 行后,可以这样做:

SELECT TOP(3) *
FROM numberedlogtable
WHERE ZipCode >= '91803'
ORDER BY ZipCode

之前选择 3 行:

SELECT TOP(3) *
FROM numberedlogtable
WHERE ZipCode < '91803'
ORDER BY ZipCode DESC

如果您愿意,请将 UNION ALL 放在这两个查询之间以使其成为一个查询。

您可以在SQL Fiddle中使用它。

于 2012-05-06T07:51:20.410 回答
0

所选邮政编码之前的 3 项和之后的 3 项

SQL 是基于设置的,它没有定义的顺序,除非您定义一个(使用 order by)。

现在,让我们不要进入更复杂的东西——首先你必须创建一个要求中心项目的订单,然后在第二个查询中你可以要求其他 6 个。抱歉,别无他法。x+3 可以使用 Top 4 语句和过滤器等 - 但之前的 3 肯定需要第二次查询。

所有人都假设您创建的查询/视图具有 * 邮政编码按定义的顺序 * 过滤后的行号,用于定义(a)“当前行”以及过滤所有具有较小行的行。

但是您需要先手动下订单。

于 2012-05-06T07:09:23.790 回答