Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询以获取另一个表中包含多行的行数_Sql_Sql Server_Group By - Fatal编程技术网

SQL查询以获取另一个表中包含多行的行数

SQL查询以获取另一个表中包含多行的行数,sql,sql-server,group-by,Sql,Sql Server,Group By,在我的应用程序中,我有一组可以在列出资源时应用的过滤器,这些过滤器通过在执行查询之前添加WHERE子句等来构建查询。这是使用SQLServer2008 我有两个相关的表,一个包含一些关于资源的静态数据,另一个包含与该资源相关的任意/可选字段 第一个表类似于此表名称和字段已更改: CREATE TABLE Resources ( ResID varbinary(28), ... extra stuff omitted type integer

在我的应用程序中,我有一组可以在列出资源时应用的过滤器,这些过滤器通过在执行查询之前添加WHERE子句等来构建查询。这是使用SQLServer2008

我有两个相关的表,一个包含一些关于资源的静态数据,另一个包含与该资源相关的任意/可选字段

第一个表类似于此表名称和字段已更改:

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