【问题标题】:Performing a query of a query on stored procedure or recommendation for best practice对存储过程的查询或最佳实践建议执行查询
【发布时间】:2014-10-31 11:50:21
【问题描述】:

我有一个存储过程,它的目的是在表中查询与声明的LocID 不匹配的行。但是,我现在要做的是根据以下行过滤掉我的数据的最佳方法:

  1. 不匹配LocID
  2. 与声明的LocID 值中的ZipCode 不匹配

代码:

DECLARE @LocID

SELECT ZipCode
            ,[Description] = ZipCode + ' - ' + Description
FROM LocMap
WHERE LocID <> @LocID

这是一个名为LocMap的表格的快速布局。

LocID | ZipCode | Description
----------------------------------
 100  | 91012   | Magical Sky
 100  | 91013   | Dream Land
 101  | 91012   | Blue Ocean
 102  | 91012   | Gray Screen
 104  | 91014   | Limit Break
 108  | 91016   | Magic Hammer

结果以 JSON 格式返回,以便根据用户从第一个下拉字段中选择的LocID 填充到表单的第二个下拉字段中。例如,如果用户从第一个下拉列表中选择LocID = 100,则存储过程将执行查询并仅返回不在LocID = 100 中的ZipCodes。在这种情况下,带有ZipCodes 91014 和 91016 的行将在第二个下拉列表中返回。

执行此操作的最佳方法是什么?这是我需要通过存储过程中的子查询来做的事情吗?我觉得我想太多了。

【问题讨论】:

  • 嘿@bman,如果它适合您,请将答案标记为已接受。谢谢!

标签: sql sql-server tsql stored-procedures


【解决方案1】:

您可以使用相关的子查询来做到这一点。请注意,您不必明确排除 @LocID,因为它也会被第二个条件排除。

select
    ZipCode,
    [Description] = ZipCode + ' - ' + Description
from
    LocMap l1
where
    Not Exists (
        select
            'x'
        from
            LocMap l2
        where
            l2.LocID = @LocID and
            l2.ZipCode = l1.ZipCode
    );

Example SQLFiddle

【讨论】:

    【解决方案2】:

    您可以通过几种不同的方式来执行此操作(将您正在查询的 LocID 的 ZipCode 存储在变量中、CTE、子查询、查询中的 LEFT OUTER JOIN 等),但在这种情况下,您实际上应该只需要检查第二个条件(zip LocID zip),因为这将解释 LocID 查找(您正在检查的 ID 的 zip 将淘汰该条目)。

    在那之后,你应该很好地使用子查询:

    DECLARE @LocID INT;
    
    SELECT
        l.[ZipCode],
        [Description] = l.ZipCode + ' - ' + l.Description
    FROM LocMap l
    WHERE l.ZipCode NOT IN (
        SELECT l2.ZipCode
        FROM LocMap l2
        WHERE l2.LocID = @LocID
    );
    

    当然,运行SET STATISTICS IO ON/检查实际的执行计划以确保它执行良好。你也可以在这里走 CTE / join 路线,但它可能会产生相同的查询计划,所以我将从这里开始。这真的取决于which is a better fit的情况。

    【讨论】:

    • 这对我来说似乎是最佳查询。
    【解决方案3】:

    关于“过度思考”,您不需要存储过程 - 您只需要查询。恕我直言,stored procedures are to be avoided wherever possible.

    这个查询会做:

    select
      a.ZipCode,
      a.ZipCode + '-' + a.Description as Description
    from LocMap a
    left join LocMap b on b.locid = 100
      and a.ZipCode = b.ZipCode
    where a.locid != 100
    and b.ZipCode is null
    

    这通过在连接到自身时查找匹配的 ZipCode 上的缺失连接来工作,并且应该显着优于非连接方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-12
      • 2013-05-10
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 2013-10-02
      • 2013-01-06
      • 1970-01-01
      相关资源
      最近更新 更多