SQL query to get count of rows with more than one row in another table

偶尔善良 提交于 2019-12-23 17:35:07

问题


Within my application, I have a set of filters that can be applied when listing resources, which builds up a query by adding WHERE clauses, etc. before executing the query. This is using SQL Server 2008.

I have two pertinent tables, one which contains some static data about the resource, and another which can contain arbitrary/optional fields pertaining to that resource.

First table is something like this (table names & fields changed):

CREATE TABLE Resources (
    ResID       varbinary(28),

    ... extra stuff omitted

    type        integer );

The second table just has name/value pairs and the corresponding resource ID

CREATE TABLE ResourceFields (
    ResID       varbinary(28) NOT NULL,

    Name        nvarchar(255) NOT NULL,
    Value       nvarchar(1024) NOT NULL);

So, for this example, there could be multiple rows in 'ResourceFields' with name = 'ContactName' for the same ResID.

What I want to do is get a count of the number of rows in the 'Resources' table that have more than one 'ContactName' listed in 'ResourceFields' with 'type' equal to some value.

I came up with this (don't laugh -- I know just enough SQL to cause problems)

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;

but instead of returning the count of the number of rows (43 in my test set) in 'Resources', I get all the COUNT(rf.Value) values returned (that is, 43 individual counts).

What am I doing wrong?


回答1:


Just use your original query as a derived table (put it in a subselect):

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



回答2:


I am not really familiar with SQL Server but try:

SELECT count( r.ResID ) FROM Resources as r where 1 < (select count(rf.value) from ResourceFields AS rf where rf.ResID = r.ResID AND rf.name = 'ContactName') and r.type = 1;



回答3:


You need to pre-aggregate the count of the 'ContactName' attributes. This is perhaps most easily accomplished with a 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

Some other things to consider -
Possibly make name in ResourceFields actually be a foreign key to a different table (so changing all attributes to a different text name is trivial). This would also allow you to put information about the expected format of data in value in the referenced table, hopefully limiting invalid data (using regex masks, etc.) - you have to be extremely careful with multi-domain tables like this (generally, they shouldn't be used, but there are probably some use-cases).
Also, are you really anticipating storing 28 bytes worth of different resources? This is a rather large number... (remember that an Int is usually 4 bytes, and stores about 4 billion different values).




回答4:


Hope this helps:

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

UPDATE: Grouping removed from the subquery, which added irrelevant rows to the count.



来源:https://stackoverflow.com/questions/7029747/sql-query-to-get-count-of-rows-with-more-than-one-row-in-another-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!