SQL搜索包含多个条件的行

时间:2009-05-14 12:31:10

标签: sql

我有3张桌子

Customer
Groups
CustomerGroupJoins

要使用的字段

Customer:Key
Groups:Key
CustomerGroupJoins:KeyCustomer, KeyGroup

我需要使用密钥1,2,3

搜索所有组中的所有用户

我在思考(但不知道这是否是正确/最好的方式):

SELECT 
  * 
FROM 
  Customer 
WHERE 
  Key = (
    SELECT KeyCustomer 
    FROM   CustomerGroupJoins 
    WHERE  KeyGroup = a
  ) = (
    SELECT KeyCustomer 
    FROM   CustomerGroupJoins 
    WHERE  KeyGroup = b
  ) = (
    SELECT KeyCustomer 
    FROM   CustomerGroupJoins 
    WHERE  KeyGroup = c
  )

6 个答案:

答案 0 :(得分:2)

我创建了这个测试数据:

srh@srh@[local] =# select * from customer join customergroupjoins on customer.key = customergroupjoins.keycustomer join groups on groups.key = customergroupjoins.keygroup;
 key |  name  | keycustomer | keygroup | key |  name   
-----+--------+-------------+----------+-----+---------
   1 | fred   |           1 |        1 |   1 | alpha
   1 | fred   |           1 |        2 |   2 | beta
   1 | fred   |           1 |        3 |   3 | gamma
   2 | jim    |           2 |        1 |   1 | alpha
   2 | jim    |           2 |        2 |   2 | beta
   2 | jim    |           2 |        4 |   4 | delta
   2 | jim    |           2 |        5 |   5 | epsilon
   3 | shelia |           3 |        1 |   1 | alpha
   3 | shelia |           3 |        3 |   3 | gamma
   3 | shelia |           3 |        5 |   5 | epsilon
(10 rows)

所以“fred”是所有(alpha,beta,gamma)中唯一的客户。确定:

srh@srh@[local] =# select * from customer
  where exists (select 1 from customergroupjoins where keycustomer = customer.key and keygroup = 1)
  and exists (select 1 from customergroupjoins where keycustomer = customer.key and keygroup = 2)
  and exists (select 1 from customergroupjoins where keycustomer = customer.key and keygroup = 3);
 key | name 
-----+------
   1 | fred
(1 row)

这是一种方法。 (1,2,3) - 您已知的组密钥 - 是子查询中的参数。有人已经提到你根本不需要加入群组表。

另一种方式:

select customer.*
from customer
  join customergroupjoins g1 on g1.keycustomer = customer.key
  join customergroupjoins g2 on g2.keycustomer = customer.key
  join customergroupjoins g3 on g3.keycustomer = customer.key
where g1.keygroup = 1 and g2.keygroup = 2 and g3.keygroup = 3

查找具有所有组(g_1,g_2 ... g_N)的用户的一般问题有点棘手。上面的这些查询已连接到链接表(customergroupjoins)N次,因此它是一个不同的查询,具体取决于您要检查的组的数量。

的一种方法是创建一个临时表以用作查询参数:该表包含客户必须拥有的所有组的列表。因此,例如创建一个名为“ParamGroups”的临时表(或SQL Server上的“#ParamGroups”以将其标记为临时),使用您感兴趣的组密钥填充它,然后执行此操作:

select * from customer where key in (
    select keycustomer
    from customergroupjoins
      join paramgroup on paramgroup.keygroup = customergroupjoins.keygroup
    group by keycustomer
    having count(*) = (select count(*) from paramgroup))

此外,作为初学者,我强烈建议您查看有关数据库表和列的命名约定的建议。每个人都有不同的想法(他们可以引发圣战),但选择一些标准(如果它们不是由你决定)并坚持下去。例如,您将一个表命名为“customer”(单数),将一个表“groups”(复数)命名为看起来很糟糕。使用“id”而不是“key”更常见,并将其用作后缀(“customer_id”或“CustomerID”)而不是前缀。整个CamelCase vs old_skool参数更像是一种风格问题,主要关键是“id”-not-“table_id”。

答案 1 :(得分:1)

如果客户位于三个组中的任何中,则上述解决方案将起作用,但不会检查所有中的成员身份。

请改为尝试:

SELECT  a.*
FROM    (SELECT c.*, substring((SELECT      (', ' + cg.KeyGroup)
                                FROM        CustomerGroupJoins cg
                                WHERE       cg.KeyCustomer = c.[Key]
                                AND         cg.KeyGroup IN (1,2,3)
                                ORDER BY    cg.KeyGroup ASC
                                FOR XML PATH('')), 3, 2000) AS GroupList
        FROM    Customer AS c) AS a
WHERE   a.GroupList = ('1, 2, 3')

这也有效:

SELECT  c.*
FROM    Customer c
WHERE   c.[Key] IN  (SELECT     cg.[KeyGroup]
                    JOIN        CustomerGroupJoins cg                       WHERE       cg.KeyGroup IN (1,2,3)
                    GROUP BY    cg.KeyGroup
                    HAVING      count(*) = 3)

答案 2 :(得分:0)

也许是这样的?

SELECT c.Key, g.Key, cgj.KeyCustomer, cgj.KeyGroup
FROM Customer c
LEFT JOIN CustomerGroupJoins cgj ON cgj.KeyCustomer = c.Key
LEFT JOIN Groups g ON g.Key = cgj.KeyGroup
WHERE g.key IN (1, 2, 3)

答案 3 :(得分:0)

根据您的描述,试试这个:

SELECT * FROM Customer c
INNER JOIN CustomerGroupJoins cgj
ON c.key = cgj.keyCustomer
INNER JOIN groups g
ON cgj.keyGroup = g.key
WHERE g.key IN (1,2,3)

答案 4 :(得分:0)

SELECT *
  FROM customer c
    INNER JOIN customerGroupJoins j ON(j.customerKey = c.key)
  WHERE j.keyGroup IN (1, 2, 3)

您不需要加入groups-table,只要您只对联接表中的组密钥感兴趣。

答案 5 :(得分:0)

这是一个可能的答案,未经测试:

select custid
from CustomerGroupJoins
where groupid in (1,2,3)
group by custid
having count(*) = 3

搜索有3行with groupid 1,2或3的客户。这意味着他们在所有3个组中,因为我假设你有一个主键(custid,groupid)。