内部连接基于输入多次相同

时间:2013-07-08 19:55:04

标签: sql-server

我遇到如下情况:

  PlanID  StateID

    1   22
    2   22
    2   30
    3   7
    3   22
    3   33
    3   46
    4   22
    5   22
    12  22
    13  7
    13  22
    13  30
    13  33
    13  40
    13  46
    14  22
    15  7
    15  20
    15  22
    15  30
    15  33
    15  40
    15  46
    16  22
    17  7
    17  20
    17  22
    17  30
    17  40

现在,当用户从UI发送stateID到sql查询时,我需要找到普通的PlanID作为输出。我不知道将从UI发送多少stateID(因为它完全取决于用户的复选框列表选择)

所以如果用户发送22和7那么o / p应该是3,13,15,17 如果用户发送22,20,7,则o / p应为15,17

我到目前为止的查询是:

select a.*, b.* from 

 Plan_State a
 Inner join Plan_State b
 ON a.PlanID = b.PlanID

WHERE 
    (
        a.StateID =22
    ) AND 
    (
        b.StateID=7
    )

但是,如果用户发送超过2个stateID,该怎么办?还有一个小注意事项是,我的stateID列表以字符串形式出现(如22,7,20)

由于

4 个答案:

答案 0 :(得分:3)

如果您有可变数量的状态,请不要使用join方法。它很快就会失控。我建议更像是:

SELECT PlanID, COUNT(stateID) AS count
FROM yourtable
WHERE (stateID IN (x,x,x,x,x))
GROUP BY PlanID
HAVING count = ($number_of_states_being_searched_for)

您仍然需要计算您正在寻找的州数量,但这仍然比执行N自我加入要便宜得多。

答案 1 :(得分:2)

此查询获取所有计划,这些计划与传递的ID中的许多不同状态匹配。 <IDS>是id列表,在查询中使用了两次。

SELECT DISTINCT
  PlanID
FROM
  YourTable t
WHERE
  t.StateID in (<IDS>)
GROUP BY
  PlanID
HAVING
  COUNT('x') = 
    ( SELECT 
        COUNT(DISTINCT StateId) 
      FROM 
        YourTable st
      WHERE
        st.StateID IN (<IDS>) )

您所要做的就是在查询中插入IDS列表,因此它可能如下所示:

SELECT DISTINCT
  PlanID
FROM
  YourTable t
WHERE
  t.StateID in (1, 2, 5)
GROUP BY
  PlanID
HAVING
  COUNT('x') = 
    ( SELECT 
        COUNT(DISTINCT StateId) 
      FROM 
        YourTable st
      WHERE
        st.StateID IN (1, 2, 5) )

没有引号,没有分裂(除非你想做一些输入验证/卫生)。

如果您能够解析输入并确定其中的不同ID的数量,则可以删除子选择。它可能会快一点。

答案 2 :(得分:1)

尝试:

SELECT PlanID  
FROM this_table
GROUP BY PlanID
HAVING COUNT(DISTINCT StateID) = (SELECT COUNT(DISTINCT StateID) FROM this_table)

如果您需要所有PlanID共同使用, source

答案 3 :(得分:0)

动态查询可以帮到你。

将stateID列表作为逗号分隔参数传递给过程。然后将动态查询构建为

DECLARE @SQL VARCHAR(MAX);
SET @SQL = "SELECT PLANID FROM [table] WHERE STATEID = " + (SELECT REPLACE(@arg,","," AND STATEID = ");