SQL查询以获取另一个表中包含多行的行数
在我的应用程序中,我有一组可以在列出资源时应用的过滤器,这些过滤器通过在执行查询之前添加WHERE子句等来构建查询。这是使用SQLServer2008 我有两个相关的表,一个包含一些关于资源的静态数据,另一个包含与该资源相关的任意/可选字段 第一个表类似于此表名称和字段已更改:SQL查询以获取另一个表中包含多行的行数,sql,sql-server,group-by,Sql,Sql Server,Group By,在我的应用程序中,我有一组可以在列出资源时应用的过滤器,这些过滤器通过在执行查询之前添加WHERE子句等来构建查询。这是使用SQLServer2008 我有两个相关的表,一个包含一些关于资源的静态数据,另一个包含与该资源相关的任意/可选字段 第一个表类似于此表名称和字段已更改: CREATE TABLE Resources ( ResID varbinary(28), ... extra stuff omitted type integer
CREATE TABLE Resources (
ResID varbinary(28),
... extra stuff omitted
type integer );
第二个表只有名称/值对和相应的资源ID
CREATE TABLE ResourceFields (
ResID varbinary(28) NOT NULL,
Name nvarchar(255) NOT NULL,
Value nvarchar(1024) NOT NULL);
因此,在本例中,“ResourceFields”中可能有多行名称为“ContactName”的相同ResID
我要做的是获取“Resources”表中的行数,这些行在“ResourceFields”中列出了多个“ContactName”,且“type”等于某个值
我想出了这个“别笑”——我知道的SQL足以引起问题
SELECT count(r.ResID)
FROM Resources as r
INNER JOIN ResourceFields AS rf
ON rf.ResID = r.ResID
AND rf.name = 'ContactName'
WHERE r.type = 1
GROUP BY rf.ResID
HAVING COUNT(rf.Value) > 1;
但不是在“资源”中返回测试集中43行的计数,而是返回所有COUNTrf.Value值,即43个单独的计数
我做错了什么?我对SQL Server不太熟悉,但请尝试:
只需将原始查询用作派生表,然后将其放入子选择中:
SELECT COUNT(*)
FROM (
SELECT count(*) AS C
FROM Resources as r
INNER JOIN ResourceFields AS rf
ON rf.ResID = r.ResID
AND rf.name = 'ContactName'
WHERE r.type = 1
GROUP BY rf.ResID
HAVING COUNT(rf.Value) > 1;
) s
您需要预先聚合“ContactName”属性的计数。这可能最容易通过CTE实现:
WITH Multiple_Contacts (ResID) as (SELECT a.ResID
FROM Resources as a
JOIN ResourceFields as B
ON b.ResID = A.ResID
AND b.name = 'ContactName'
WHERE a.type = 1
GROUP BY a.ResID
HAVING COUNT(a.ResId) > 1)
SELECT COUNT(ResId)
FROM Multiple_Contacts
其他一些需要考虑的事情 可能使ResourceFields中的名称实际上是另一个表的外键,因此将所有属性更改为不同的文本名称并不重要。这还允许您将有关预期数据格式的信息以值的形式放入引用的表中,希望使用正则表达式掩码限制无效数据,等等。对于这样的多域表,您必须非常小心,通常不应该使用它们,但可能有一些使用案例。 另外,您真的期望存储28字节的不同资源吗?这是一个相当大的数字。。。请记住,Int通常是4个字节,并存储大约40亿个不同的值。
希望这有帮助:SELECT COUNT(*)
FROM Resources as r
WHERE EXISTS (
SELECT 1
FROM ResourceFields rf
WHERE rf.ResId = r.ResId
AND rf.name = 'ContactName'
HAVING COUNT(*) > 1
)
AND r.type = 1
更新:从子查询中删除分组,这会将不相关的行添加到计数中。他可能实际上想要一个内部计数的总和,但在其他方面我喜欢这个。是的,他肯定会。然而,到目前为止,他已经声明他希望得到43行值,但是得到了43行值。不,我只想要计数。我会试试这个。只是出于好奇,尾随的“s”是什么意思?在这种情况下,它是子选择项不需要的名称,如s-如果你想将其与其他内容连接,你可以使用s访问子选择项列,在这种情况下,只需C…这实际上返回了79,所以我认为它在子查询中双重包含了一些行。是的,我太依赖于现有的查询了。现在,它应该像预期的那样工作。
SELECT COUNT(*)
FROM Resources as r
WHERE EXISTS (
SELECT 1
FROM ResourceFields rf
WHERE rf.ResId = r.ResId
AND rf.name = 'ContactName'
HAVING COUNT(*) > 1
)
AND r.type = 1