SQL选择具有一个值而不是另一个值的行

时间:2016-06-09 14:27:30

标签: sql-server-2008

我在SQL中有一个表,它包含一个id的多行,如下所示

accountid   Productname
1           GL
1           IP
1           MI
2           GL
2           IP
2           PA
3           MI
3           CP
3           IP
4           GL
4           CP
4           CI

我希望能够选择所有包含某些产品而非其他产品的帐户。例如,所有具有IP或GL但不具有MI的,使用上面的示例表将返回帐户2和4。

SELECT ccx_accountidname
FROM (
    SELECT ccx_accountidname, ccx_productname
    FROM Filteredccx_leadresearch
    WHERE ccx_productname IN ('GL','IP')
    AND ccx_accountidname IS NOT NULL
    ) AS T
WHERE ccx_productname NOT IN ('MI')
ORDER BY ccx_accountidname

SELECT DISTINCT LR1.ccx_accountidname
FROM Filteredccx_leadresearch LR1
LEFT JOIN Filteredccx_leadresearch LR2 ON LR1.ccx_accountid =   LR2.ccx_accountid 
AND LR2.ccx_productname IN ('GL', 'IP')
WHERE LR1.ccx_productname NOT IN ('MI')
AND LR1.ccx_accountidname IS NOT NULL
ORDER BY LR1.ccx_accountidname

两者都给出了基本相同的结果,有什么办法可以做到吗?

提前感谢您提供任何帮助

5 个答案:

答案 0 :(得分:0)

你可以试试这个:

SELECT DISTINCT T1.Accountidname FROM TheTableThatContainsAccountnames as T1
JOIN AccountProductsTable as T2 on T1.AccountId=T2.AccountId
WHERE T2.ProductName = 'ProductYouWant'
AND T2.ProductName = 'AnOtherProductYouWant'

答案 1 :(得分:0)

根据你的帖子,你真正需要的是一个简单的查询,正确和逻辑。您希望所有帐户的产品名称为GL或IP,但不在MI中。这将在没有任何其他连接的情况下完成。

Max

修改

这将为您提供帐户,但我怀疑它会在您的整体解决方案中有效。没有看到完整的数据集就很难说清楚。这也可以通过参数完成。

  SELECT ccx_accountidname
  FROM Filteredccx_leadresearch
  WHERE 
       ccx_productname in ('GL','IP')
       and ccx_productname not in ('MI')

答案 2 :(得分:0)

我可能迟到了比赛,但是如果有人试图解决类似的问题,这应该可以解决问题。我重命名了您的表格及其列:

Filteredccx_leadresearch -> l_search
ccx_accountidname -> a_name
ccx_productname -> p_name

这是SQL:

(SELECT DISTINCT t1.a_name
   FROM l_search t1
   JOIN l_search t2 ON t1.a_name = t2.a_name
   WHERE t1.p_name = 'IP'
     OR t2.p_name = 'GL') 

MINUS

(SELECT DISTINCT t1.a_name
   FROM l_search t1
   JOIN l_search t2 ON t1.a_name = t2.a_name
   WHERE ((t1.p_name = 'IP'OR t1.p_name = 'GL') AND t2.p_name = 'MI')
     OR 
         (t1.p_name = 'MI' AND (t1.p_name = 'IP' OR t1.p_name = 'GL')));

第一组:
在具有相同ID的表本身上进行叉乘积运算,获得具有乘积“ IP”或“ GL”的帐户ID。

第二组:
表具有相同ID的叉积,获得第一个叉属性为p_name('IP'或'GL'),第二个为'MI'的帐户ID。
另外,获得那些ID相同但又相反的ID:第一个交叉属性为p_name'MI',第二个交叉属性为('IP'或'GL')。

最后从第一中减去第二

答案 3 :(得分:0)

这里是一种简单的方法,可以包含与IP或GL匹配的帐户,如果这些帐户具有MI记录而不使用子查询,则可以排除这些帐户。

这是假设t1是一个在accountid中具有唯一帐号的表,而t2是上面显示的具有accountid和Productname列的表。

SELECT DISTINCT
    t1.accountid
FROM t1
    LEFT JOIN t2 AS t2_match
        ON t1.accountid = t2_match.accountid
        AND
        (
            t2_match.Productname = 'IP'
            OR t2_match.Productname = 'GL'
        )
    LEFT JOIN t2 AS t2_not_match
        ON t1.accountid = t2_not_match.accountid
        AND t2_not_match.Productname = 'MI'
WHERE
    t2_match.accountid IS NOT NULL
    AND t2_not_match.accountid IS NULL

答案 4 :(得分:0)

这真的很晚,但它可能对某些人有所帮助。

我将只专注于使用我们显示的表格中的列(不会将它与我们没有给出的其他表格结合起来)。

由于示例中唯一的表没有明确命名,我将其称为}


some_table

这里的想法是:

  1. 选择所有具有 productnameSELECT t.accountidname, t.productname FROM some_table t WHERE t.productname IN ('GL','IP') AND t.accountidname NOT IN ( SELECT accountidname FROM some_table WHERE productname = 'MI' ); GL(第三行)的 accountidproductname立>
  2. 选择所有具有 productname IPaccountid 并将它们从我们已有的值中删除(从第 4 行开始)

有了这些值,过滤或将它与其他表结合起来应该是微不足道的。

如果 accountidproductname 的组合可以在表中重复,您可能希望将 MI 替换为 SELECT。 >