使用join语句过滤查询

时间:2013-03-05 15:03:52

标签: sql sql-server sql-server-2005

我正在使用ColdFusion 8来开发我公司的网站,并希望从不同表中没有匹配的表(clientname)中返回记录列表(只是dbo.clients字段) (dbo.fees)用于提示最终用户为这些公司添加费用表。一个例子:

dbo.clients

CLIENT_ID CLIENT_NAME
1         Joe's Diner
2         Save-a-Lot
3         Family Meds
4         DiFazio's

dbo.fees

CID        CLIENT_NAME  FEE
1          Joe's Diner  25.000
2          Save-a-Lot   35.000
4          DiFazio's    30.000

我想要的是一个结果集,在上述表/数据的情况下,只返回clientid / clientname 3 / Family Meds,因为它们没有在表dbo.fees中列出费用/记录。我的数据库是MSSQL 2005.我的查询是:

SELECT clientid 
FROM clients 
INNER JOIN fees 
  ON clients.clientid <> fees.cid;

返回50,000+结果的笛卡儿积。使用LEFT/RIGHT OUTER JOIN仍然会向我提供笛卡尔积,而DISTINCT只会返回dbo.clients中的每条记录,无论它们是否有dbo.fees条目。我究竟做错了什么?

P.S。另外值得注意的是:在我之前的管理员显然没有在客户/费用表之间建立PK / FK关系,因此任何可能依赖于它的查询语法在这种情况下可能不起作用。它可能必须完全基于相关领域的价值。

2 个答案:

答案 0 :(得分:1)

您可以将LEFT JOINWHERE子句一起使用,该子句仅返回fees表中未显示的记录:

select c.CLIENT_ID, c.CLIENT_NAME
from clients c
left join fees f
    on c.CLIENT_ID = f.CLIENT_ID
where f.CLIENT_ID is null

如果您需要帮助学习JOIN语法,这里有一个很好的参考:

这也可以使用NOT EXISTS

编写
select *
from clients c
where not exists (select CLIENT_ID
                    from fees f
                    where c.CLIENT_ID = f.CLIENT_ID)

请同时查看SQL Fiddle Demo两次查询

答案 1 :(得分:1)

最简单,你可以使用NOT IN;

SELECT clientid FROM clients WHERE clientid NOT IN
  (SELECT clientid FROM fees)

...或者你可以使用LEFT JOIN来更详细地做同样的事情;如果客户不存在费用,则f.clientid将为NULL。

SELECT c.clientid
FROM clients c
LEFT JOIN fees f
ON c.clientid = f.clientid
WHERE f.clientid IS NULL