存储过程:通过匹配输入参数进行选择或返回空记录

时间:2017-05-09 19:36:39

标签: sql sql-server database tsql stored-procedures

我有以下情况:

有一个这样的表:

Id     | Param  | Value
------ | ------ | -------------
1      | 1      | One 1
1      | NULL   | Null-Value 1
1      | 2      | Two 1
1      | 3      | Three 3
2      | NULL   | Nul-Value 2
2      | 2      | Two 2
3      | NULL   | Null-Value 3
4      | 1      | One 4
5      | NULL   | Null-Vaue  5
6      | NULL   | Null-Value 6

我必须通过给定的输入可为空参数来编写存储过程,用于" Param"我必须生成一个结果,其中包含一个具有ID和Value的表,结果基于逻辑 -

如果输入参数为null - 返回Param为空值的所有行

如果参数不为null,则返回与Param列中该参数匹配的行以及所有行(对于其他ID),其值为Param。

每个ID必须只有一个结果

考虑在Id和Param列上应用了唯一的复合索引。

示例:

Input parameter: 1

Output table:

Id | Value
-- | -------------
1  | One 1
2  | Nul-Value 2
3  | Null-Value 3
4  | One 4
5  | Null-Vaue  5
6  | Null-Value 6

示例2(让我包括Param列以获得更好的可见性):

Input parameter: 2

Output table:

Id | Param | Value
-- | ----- |-------------
1  | 2     |Two 1
2  | 2     |Two 2
3  | NULL  |Null-Value 3
5  | NULL  |Null-Value 5
6  | NULL  |Null-Value 6
  • 我想这将是桌子与自身的连接,或者甚至更好的交叉(或者可能是外部)应用和一些适当的where子句......

3 个答案:

答案 0 :(得分:1)

这解决了每个id多个结果的问题。您没有为每个ID提供您想要的规则,因此我无法执行下一步。

for c in lp.constraints.itervalues():
    if not c.valid(0):
        print c.name, c.value()

如果您不关心每个ID超过一​​个时返回哪一个,这将有效:

SELECT *
FROM tableyoudidnotsaythenameof as x
WHERE (coalesce(x.value, @inparam) = @inparam) or
      (@inparam is null and x.value is null)

用更大的rn:

对空值进行排序
SELECT * 
FROM (
  SELECT *, row_number() over (partition by id) as rn
  FROM tableyoudidnotsaythenameof as x
  WHERE (coalesce(x.value, @inparam) = @inparam) or
        (@inparam is null and x.value is null)
) zed
WHERE zed.rn = 1

答案 1 :(得分:0)

您可以在不使用连接的情况下使用此方法。当@param为null时,它返回所有行。

- name: whatever
  hosts: whatever
  tasks:
    - name: echo
      shell: echo {{ argument | regex_replace('-a','-b') }}

答案 2 :(得分:0)

我明白了。这是查询:

declare @input int = 2

select t.Id, t.Value
from [dbo].[MyTable] t
outer apply (select * from MyTable t2
             where t2.Param = @input
             and t.Id = t2.Id) mt
where  (t.Id = mt.Id and t.Param = @input)
or (t.Param is null and mt.Param is null)