SQL Server Problem counting values over fixed amount of other values

34gzjxbg  于 2023-04-28  发布在  其他
关注(0)|答案(2)|浏览(148)

UPDATE:

Finally, I got a fiddle together. I believe this makes it way more clear what I'm trying to achieve.

Please see http://sqlfiddle.com/#!18/fee65/1/0

My expected output is:
| Name | Count | SID |
| ------------ | ------------ | ------------ |
| VLAN115 | 3 | S-1 |
| VLAN116 | 2 | S-2 |
| VLAN118 | 4 | S-3 |

As you can see there're more VLAN's that 115, 116, 118. But I only need those three and count how many times the occur in COS_AD_memberOf.

Not sure about SIDs as they're unique so would be 3, 2, and 4 times the unique SID value in that column?

INITIAL POST

I have three names I want to check ('Name' column; more exist in the table) and I want to count the number of occurrences of them where they match part of the value of column 'COS_AD_memberOf'.

However, I'm only getting the same 'Count' for each of those three 'Name' column values.

SELECT COS_AD_name AS Name,
    (
    SELECT COUNT(*)
    FROM CacheOrganizationStructure
    WHERE COS_AD_memberOf LIKE '%VLAN115%'
        OR COS_AD_memberOf LIKE '%VLAN116%'
        OR COS_AD_memberOf LIKE '%VLAN118%') AS Count,
    COS_SID AS SID
FROM CacheOrganizationStructure
WHERE COS_AD_name LIKE '%VLAN115%' OR COS_AD_name
    LIKE '%VLAN116%' OR COS_AD_name
    LIKE '%VLAN118%'
ORDER BY Name ASC
NameCountSID
VLAN115166S-1
VLAN116166S-2
VLAN118166S-3

How can I amend the query so that it actually counts correctly?

0dxa2lsx

0dxa2lsx1#

You can use ROW_NUMBER to solve the problem

select 
        
       case 
           when COS_AD_memberOfn=1 then 'VLAN115'
           when COS_AD_memberOfn=2 then 'VLAN116'
           when COS_AD_memberOfn=3 then 'VLAN118'
           else 'other' end as Name
       ,c
from (
        select *,count(*) over(partition by COS_AD_memberOfn ) as c
               ,ROW_NUMBER() over(partition by COS_AD_memberOfn order by COS_SID ) as rw
        from (
                select
                case
                       when COS_AD_memberOf LIKE '%VLAN115%' then 1
                       when COS_AD_memberOf LIKE '%VLAN116%' then 2
                       when COS_AD_memberOf LIKE '%VLAN118%' then 3
                       else  0 end as COS_AD_memberOfn
                       ,COS_SID
                       ,COS_AD_name
                       ,COS_AD_memberOf
                from CacheOrganizationStructure
                WHERE COS_AD_name LIKE '%VLAN115%' OR COS_AD_name
                    LIKE '%VLAN116%' OR COS_AD_name
                    LIKE '%VLAN118%'
        )a
        

)a
where rw=1
ORDER BY a.COS_AD_name ASC

example:

COS_AD_memberOfCOS_AD_nameCOS_SID
aaVLAN115aaaaVLAN115aa2
bbVLAN115aabbVLAN115aa2
aaVLAN116aaVLAN1163
VLAN118ssVLAN118ssss3

expected

Namec
VLAN1152
VLAN1161
VLAN1181
jv4diomz

jv4diomz2#

You can use PATINDEX inside a subquery to calulcate the relevant value, then use a windowed count using PARTITION BY to get that.

SELECT
  *,
  count = COUNT(*) OVER (PARTITION BY v.VlanValue)
FROM CacheOrganizationStructure
CROSS APPLY (VALUES(
    CASE WHEN PATINDEX('%VLAN115%', COS_AD_memberOf) > 0 THEN 115
         WHEN PATINDEX('%VLAN116%', COS_AD_memberOf) > 0 THEN 116
         WHEN PATINDEX('%VLAN118%', COS_AD_memberOf) > 0 THEN 118
    END
)) v(VlanValue);

An alternative is to use a combination of PATINDEX and SUBSTRING to pull the value out.

SELECT
  *,
  count = COUNT(*) OVER (PARTITION BY v.VlanValue)
FROM CacheOrganizationStructure
CROSS APPLY (VALUES(
    SUBSTRING(COS_AD_memberOf, NULLIF(PATINDEX('%VLAN[0-9][0-9][0-9]%', COS_AD_memberOf), 0), 7)
)) v(VlanValue);

You don't have to use windowing functions. A normal GROUP BY also works, and will aggregate up all the rows.

SELECT
  v.VlanValue,
  count = COUNT(*),
  Sids = STRING_AGG(COS_SID, ', ')
FROM CacheOrganizationStructure
CROSS APPLY (VALUES(
    SUBSTRING(COS_AD_memberOf, NULLIF(PATINDEX('%VLAN[0-9][0-9][0-9]%', COS_AD_memberOf), 0), 7)
)) v(VlanValue)
GROUP BY
  v.VlanValue;

SQL Fiddle

相关问题