如何检查一个表中指定数量的条目是否与另一个表中的实际条目数相匹配?

时间:2014-06-10 03:27:54

标签: sql sql-server sql-server-2008

我有两个表,一个用于主要,一个用于内容

'主'表:

pkey - pkey2  - contents

ABC1 - 11324  - 3
KJPO - 14124  - 4
PJKJ - 767172 - 5

'内容'表

pkey - pkey2  - details

ABC1 - 11324  - some random info here
ABC1 - 11324  - some random info here
ABC1 - 11324  - some random info here
KJPO - 14124  - some random info here
KJPO - 14124  - some random info here
KJPO - 14124  - some random info here

'Main'表指定应连接到'Main'表的最大内容数。

我在查询中需要的是从'Main'表中获取相应'Contents'尚未完成的行

即。与主表中的条目匹配的行数未达到(不等于)“Main”表中指定的内容数。

它应该返回(基于上面的例子),如下所示:

'主'表:

pkey - pkey2  - contents - missing

KJPO - 14124  - 4        - 1
PJKJ - 767172 - 5        - 5

我尝试过制作内连接,但无法找到它。 我正在考虑在客户端这样做,例如vb.NET但我知道这不是推荐的方法。我希望有人可以帮助我或至少引导我另一个解决方案/解决方法,提前谢谢

编辑:

我在这里添加了来自dav1dsmith的代码:

select m.pkey, m.pkey2, m.contents, m.contents-isnull(c.actual,0) as missing
from dbo.Main m
left join (
    select pkey, pkey2, count(*) as actual
    from dbo.Contents
    group by pkey, pkey2
) c on c.pkey=m.pkey and c.pkey2=m.pkey2
where c.actual<>m.contents

代码有效,但结果不包含'main'表中的条目,其中'contents'表中没有相应的条目..它显示的行不完整但仅适用于至少有一个条目的行在内容表..正如我所说,代码工作,但我仍然试图编辑它,以提供我需要的东西

3 个答案:

答案 0 :(得分:3)

select m.pkey, m.pkey2, m.contents, m.contents-isnull(c.actual,0) as missing
from dbo.Main m
left join (
    select pkey, pkey2, count(*) as actual
    from dbo.Contents
    group by pkey, pkey2
) c on c.pkey=m.pkey and c.pkey2=m.pkey2
where isnull(c.actual,0)<>m.contents

派生表ccount(*)dbo.contents的每个组合解析pkey中的pkey2行。显然,任何不存在的组合都不会在c中返回一行。 dbo.mainleft join被添加到这些结果中 - 因此无论在汇总的main表中是否存在任何行,都会在结果集中返回contents中的每一行 - 使用相同的键列。 where子句筛选出contents中与main表中预测的行数相同的行(我最初忘记了isnull() - 这是丢弃的行来自main,其中不存在相应的c行。然后,初始列列表执行数学计算missing列值。

答案 1 :(得分:2)

请告诉我此查询是否有效 -

select s1.pkey, s1.pkey2, s1.contents, (s1.contents - s2.cnt1) as missing
from
(
select pkey, pkey2, contents 
from Main
) as s1
left join
(
select pkey, count(pkey2) as cnt1
from Contents
group by pkey
)as s2
on s1.pkey = s2.pkey
where (s1.contents - s2.cnt1) > 0

答案 2 :(得分:0)

正如dav1dsm1th所解释的那样,删除的行来自NULL条件中的WHERE值(NULL的条件始终返回FALSE)。

实际上可以删除子查询并将分组引发到主查询

SELECT m.pkey, m.pkey2, m.contents
     , missing = m.contents - COUNT(c.Details)
FROM   main m
       LEFT JOIN Contents c ON m.pkey = c.pkey and m.pkey2 = c.pkey2
GROUP BY m.pkey, m.pkey2, m.contents
HAVING m.contents <> COUNT(c.Details)

这样做COUNT将始终返回一些内容,即使这两个表之间没有匹配。