SQL Query数据基于变量

时间:2018-04-02 22:03:41

标签: sql sql-server stored-procedures

我有一个简单的查询,我正在尝试适应新的情况。对于这种情况,如果变量locationID=1,则我需要所有记录,而不管其locationID

但是,如果它不等于1,我只需要提供与@locationID匹配的记录。

以下是我的设置示例:

DECLARE @locationID INT = 1; -- All Results Regardless of locationID
--DECLARE @locationID INT = 2; -- Only results that match this locationID (2)
--DECLARE @locationID INT = 3; -- Only results that match this locationID (3)

-- Temp Data
DECLARE @temp AS TABLE (color VARCHAR(10), locationID INT, name VARCHAR(20))
INSERT INTO @temp( color, locationID, name  )VALUES  ( 'Blue', 1, 'Test 1' )
INSERT INTO @temp( color, locationID, name ) VALUES  ( 'Red', 2, 'Test 2' )
INSERT INTO @temp( color, locationID, name ) VALUES  ( 'Red', 1, 'Test 3' )
INSERT INTO @temp( color, locationID, name ) VALUES  ( 'Red', 2, 'Test 4' )
INSERT INTO @temp( color, locationID, name ) VALUES  ( 'Red', 3, 'Test 5' )

-- Query
SELECT * 
FROM @temp
WHERE
locationID = ...

我想弄清楚我是否需​​要使用CASE WHEN或其他方法。

5 个答案:

答案 0 :(得分:7)

WHERE (locationID = @LocationId OR @locationID = 1)

答案 1 :(得分:4)

试试这个:

<select id="Type" name="Type"><option value="">Type</option>
<option value="/?id=na">Ring1</option>
<option value="/?id=na">Ring</option>
</select>

答案 2 :(得分:1)

这似乎非常简单,也许我不理解你的问题。如果要通过变量值进行查询,则只需使用变量值:

"AnsibleError: teme templating string: Encountered unknown tag 'do'. Jinja was looking for th: 'endfor' or 'else'

答案 3 :(得分:1)

那么变量应该是1还是locationid? 你可以使用IN。

... WHERE @LocationID IN (1, LocationID)

示例代码段:

declare @locationID int;

-- Test data using a table variable
declare @varTable table (id int identity(1,1) primary key, locationID int, name varchar(20), color varchar(10));
insert into @varTable (locationID, name, color) values  
(1,'Test 1','Blue'),
(2,'Test 2','Red'),
(1,'Test 3','Red'),
(2,'Test 4','Red'),
(3,'Test 5','Red');

-- Returning all records
set @locationID = 1;
SELECT t.* FROM @varTable t WHERE @locationID IN (1, t.locationID);

-- Only returning those with locationID = 2
set @locationID = 2;
SELECT t.* FROM @varTable t WHERE @locationID IN (1, t.locationID);

答案 4 :(得分:1)

其他一些想法。由于使用常量1不是直观或自我记录,您可以将其默认为NULL。然后说:

WHERE LocationID = COALESCE(@LocationID, LocationID);

如果LocationID列可以为空,那么您可以使用一些至少比1更自我记录的令牌值,例如-1(因为我没有&#39;认为任何查看代码的人都会立即知道LocationID = 1}中确实存在无效的行:

WHERE LocationID = COALESCE(NULLIF(@LocationID, -1), LocationID);

这很容易受到参数嗅探的影响,因此如果您发现经常在&#34;所有行&#34;之间切换,您可能需要添加OPTION (RECOMPILE)。和#34;非常具体的行。&#34;您也可以使用动态SQL来选择性地构建WHERE子句,假设您的真实场景使用真实的表:

DECLARE @sql nvarchar(max) = N'SELECT ... FROM dbo.RealTable'
IF @LocationID <> 1 -- or IS NOT NULL or <> -1 or what have you
BEGIN
  SET @sql += N' WHERE LocationID = @LocationID';
END
EXEC sys.sp_executesql @sql, N'@LocationID int', @LocationID;

通过这种方式,您可以在包含参数时获得不同的计划,而不包含参数,这不会使扫描(您需要所有行的位置)变得更好,但它可以防范您的情况对所有行使用seek + lookup,这可能非常糟糕。更常见的是,它可以防止您在真正使用搜索时获得可怕的全表/索引扫描。但是,这种方式完全取决于第一次运行查询的情况。

即使在这里,如果跨越不同OPTION (RECOMPILE)值的数据分布(或可能稍后变得严重偏差),您可能希望在@sql的末尾使用LocationID

我称这种类型的查询&#34;厨房水槽,&#34;并在此处写到: