Help with an SMS Report (Full Version)

All Forums >> [Management Products] >> Microsoft Systems Management Server >> Web Reporting



Message


Tom_Watson -> Help with an SMS Report (6/5/2008 10:36:04 AM)

I’m looking for a little help with a report I’m trying to build.  A basic description of what I am trying to do is compare the number of collection members for two collections (CollectionID: ABC0001F' and CollectionID: ABC00062), and I’m looking to do this per site.

As a starting point I did a quick report like so:-

quote:

SELECT   SiteCode,
        CollectionID,
        COUNT(ResourceID) AS [Count]
FROM     dbo.v_FullCollectionMembership
WHERE    CollectionID = 'ABC0001F' OR CollectionID = 'ABC00062'
GROUP BY SiteCode, CollectionID
ORDER BY SiteCode, CollectionID


This gives me a list like:-

Site Code|Collection ID|Count
ABC      |ABC0001F     |23
ABC      |ABC00062     |159
DEF      |ABC0001F     |37
DEF      |ABC00062     |634
GHI      |ABC0001F     |2
GHI      |ABC00062     |35


Etc…

However, what I’d really like to see is something like:-

Site Code|Collection ABC0001F Count|Collection ABC00062 Count
ABC      |23                       |159
DEF      |37                       |634
GHI      |2                        |35


Etc…

Maybe even add a 4th column with the difference between the two (column 3 minus column 2), and a final column with a percentage (column 4 divided by column 3).

My environment is SMS 2003 SP3 with SQL 2000 SP4, though we may be moving to SQL 2005 in a couple of weeks.

Tom Watson 




Chr15Murr4y -> RE: Help with an SMS Report (6/5/2008 1:00:36 PM)

Hi Tom

I've not got access to test this right now but it should be something like this for the simple one..

SELECT distinct
colmem1.SiteCode,
(Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC0001F') as [Collection ABC0001F Count],
(Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC00062') as [Collection ABC00062 Count]
FROM     dbo.v_FullCollectionMembership colmem1
ORDER BY SiteCode

Or this if you want the difference and percentage.

SELECT distinct
colmem1.SiteCode,
(Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC0001F') as [Collection ABC0001F Count],
(Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC00062') as [Collection ABC00062 Count],
((Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC00062') - (Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC0001F')) as [Difference],
(((Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC00062') - (Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC0001F')) / (Select Count(colmem2.ResourceID) from dbo.v_FullCollectionMembership colmem2 where colmem2.sitecode = colmem1.sitecode and colmem2.collectionid = 'ABC00062')) as [Percentage]
FROM     dbo.v_FullCollectionMembership colmem1
ORDER BY SiteCode

It's not exactly refined, and it could be re-written a lot better but without being able to test it for you i wanted to leave it as uncomplicated as possible. You could replace the collections with variables too if you want.

Hope this works, i'll be able to test it tomorrow if it doesn't

C




jnelson993 -> RE: Help with an SMS Report (6/5/2008 5:16:54 PM)

Hey Tom!

If you've got SQL 2005, we can make that even more sexy by using a PIVOT.

SELECT
  SiteCode AS [Site Code],
  [ABC0001F] AS [Collection ABC0001F Count],
  [ABC00062] AS [Collection ABC00062 Count],
  [ABC00062]-[ABC0001F] AS [Difference],
  ([ABC00062]-[ABC0001F])*100.0/[ABC00062] AS [Percentage]
FROM
(SELECT  
     SiteCode,
     CollectionID,
     ResourceID
  FROM    
     dbo.v_FullCollectionMembership
  WHERE
     CollectionID IN('ABC0001F','ABC00062')) as cnts
  PIVOT
  (COUNT(cnts.resourceID)
   FOR cnts.CollectionID IN ([ABC0001F],[ABC00062])) as pvt







Tom_Watson -> RE: Help with an SMS Report (6/6/2008 3:28:07 AM)

Thanks John/Chris.

We may be going to SQL 2005 as ealy as next Wednesday.  So good news for everyone looking to use PIVOTs...

I'll give both of these samples a whirl, and let you know how they pan out.

PS. John, I have been doing a little bit more learning T-SQL, using the T-SQL Recipes book and a local install of SQL Express.  However, sometimes there are certain things I still can't get my head around.  At least as quick as some.

Cheers,
Tom




Tom_Watson -> RE: Help with an SMS Report (6/6/2008 7:04:01 AM)

Chris,

Your reports work as expected.

I may have to tinker with your second one slightly, as for one of the sites, both collections have 0 members, so when you work out the percentage you get a divide by zero error.

John, I'll have to wait for the sexy version until next week, when the SQL 2005 upgrade happens.

Thanks guys..

Tom Watson




Tom_Watson -> RE: Help with an SMS Report (6/6/2008 9:06:28 AM)

I tried using :-

SET ARITHABORT OFF
SET ANSI_WARNINGS OFF

from http://www.sql-server-helper.com/error-messages/msg-8134.aspx

but it looks like Web Reports don't like this.  It works OK in SQL Query Analyser though.

Anyway, I've used so far (based on Chris's second report):-

quote:

SELECT   DISTINCT colmem1.SiteCode,
                (SELECT COUNT(colmem2.ResourceID)
                 FROM   dbo.v_FullCollectionMembership colmem2
                 WHERE  colmem2.sitecode = colmem1.sitecode
                        AND colmem2.collectionid = 'ABC0001F') AS [Collection ABC0001F Count],
                (SELECT COUNT(colmem2.ResourceID)
                 FROM   dbo.v_FullCollectionMembership colmem2
                 WHERE  colmem2.sitecode = colmem1.sitecode
                        AND colmem2.collectionid = 'ABC00062') AS [Collection ABC00062 Count],
                ((SELECT COUNT(colmem2.ResourceID)
                  FROM   dbo.v_FullCollectionMembership colmem2
                  WHERE  colmem2.sitecode = colmem1.sitecode
                         AND colmem2.collectionid = 'ABC00062')
              - (SELECT COUNT(colmem2.ResourceID)
                  FROM   dbo.v_FullCollectionMembership colmem2
                  WHERE  colmem2.sitecode = colmem1.sitecode
                  AND colmem2.collectionid = 'ABC0001F')) AS [Difference],
                CASE
                  WHEN (SELECT COUNT(colmem2.ResourceID)
                        FROM   dbo.v_FullCollectionMembership colmem2
                        WHERE  colmem2.sitecode = colmem1.sitecode
                               AND colmem2.collectionid = 'ABC00062') = 0 THEN 100
                  ELSE (((SELECT COUNT(colmem2.ResourceID)
                          FROM   dbo.v_FullCollectionMembership colmem2
                          WHERE  colmem2.sitecode = colmem1.sitecode
                                 AND colmem2.collectionid = 'ABC00062')
                      - (SELECT COUNT(colmem2.ResourceID)
                          FROM   dbo.v_FullCollectionMembership colmem2
                          WHERE  colmem2.sitecode = colmem1.sitecode
                          AND colmem2.collectionid = 'ABC0001F'))
                       * 100
                      / (SELECT COUNT(colmem2.ResourceID)
                          FROM   dbo.v_FullCollectionMembership colmem2
                          WHERE  colmem2.sitecode = colmem1.sitecode
                          AND colmem2.collectionid = 'ABC00062'))
                END AS [Percentage]
FROM     dbo.v_FullCollectionMembership colmem1
ORDER BY SiteCode


It's starting to look like what I'm after.

Regards,
Tom Watson




jnelson993 -> RE: Help with an SMS Report (6/6/2008 5:01:13 PM)

AHHH, it burns my eyes!!!!

:)

I think everyone's way overthinking this.  Just create a query that counts them per collectionID/siteCode, then select from that query like a table (called a derived table for those that don't know) and do the math.  In my case, if you have a 0 for ABC00062 it won't do the division, it will just return NULL

SELECT
  cnt.SiteCode,
  cnt.ABC0001F AS [Collection ABC0001F Count],
  cnt.ABC00062 AS [Collection ABC00062 Count],
  cnt.ABC00062 - cnt.ABC0001F AS [Difference],
  CASE
     WHEN cnt.ABC00062 = 0 THEN NULL
     ELSE (cnt.ABC00062 - cnt.ABC0001F)*100.0/cnt.ABC00062
  END AS [Percentage]
FROM
(SELECT
     fcm.SiteCode,
     SUM(CASE fcm.CollectionID WHEN 'ABC0001F' THEN 1 ELSE 0 END) as [ABC0001F],
     SUM(CASE fcm.CollectionID WHEN 'ABC00062' THEN 1 ELSE 0 END) as [ABC00062]
  FROM
     dbo.v_FullCollectionMembership AS fcm
  WHERE
     fcm.CollectionID IN('ABC0001F','ABC00062')
  GROUP BY
     fcm.SiteCode) AS cnt







jnelson993 -> RE: Help with an SMS Report (6/6/2008 5:03:16 PM)

This is also nice on the SQL server...mine has a cost of 0.35...yours has to go to the well a bazillion times so it's got a cost of over 500 at my site.




Tom_Watson -> RE: Help with an SMS Report (6/9/2008 4:28:09 AM)

Wow.  Looks much simpler.

Tom




Tom_Watson -> RE: Help with an SMS Report (6/9/2008 5:45:22 AM)

I thought I'd make this a little more complicated again, but simpler for the project managers that need these numbers to read.  I combined this with the standard report 77 "Sites by hierarchy with time of last site status update", and got:-

quote:

set nocount on

/* order sites by hierarchy */
create table #SiteOrder
(
SiteCode char(3),
SiteLevel    int,
PreOrder int identity,
PRIMARY KEY (SiteLevel,SiteCode)
)

declare @NextS char(3)
declare @SiteLevel int

set @SiteLevel=1
set @NextS=''
/* peform a depth first search of the site table, list the sites in pre-order */
while @NextS is not null
begin
  /* find the next child node */
  select @NextS=MIN(SiteCode) from v_Site
  where ReportingSiteCode=@NextS
    and SiteCode not in (select SiteCode from #SiteOrder
                                     where SiteLevel=@SiteLevel)

  if @NextS IS NULL
  begin
     set @SiteLevel=@SiteLevel-1
     /* pop up one level and find the last parent we were working with  */
     select @NextS = SiteCode from #SiteOrder where PreOrder=
           (select MAX(PreOrder) from #SiteOrder where SiteLevel=@SiteLevel-1)
  end
  else
  begin
     insert into #SiteOrder(SiteCode,SiteLevel) values(@NextS,@SiteLevel)
     /* move down one level and and find the children of this site */
     set @SiteLevel = @SiteLevel + 1
  end 
end

/* run the query, order by PreOrder, use SPACE with SiteLevel for indentation */ 

SELECT SPACE(3*(SiteLevel-1))+so.SiteCode as SiteCode,
      s.SiteName,
      cnt.ABC0001F AS [Collection ABC0001F Count],
      cnt.ABC00062 AS [Collection ABC00062 Count],
      cnt.ABC00062 - cnt.ABC0001F AS [Difference],
CASE
      WHEN cnt.ABC00062 = 0 THEN NULL
      ELSE ROUND((cnt.ABC00062 - cnt.ABC0001F)*100.0/cnt.ABC00062, 2)
END AS [Percentage]
FROM #SiteOrder so
JOIN v_Site s ON so.SiteCode=s.SiteCode
LEFT JOIN (SELECT
             fcm.SiteCode,
             SUM(CASE fcm.CollectionID WHEN 'ABC0001F' THEN 1 ELSE 0 END) as [ABC0001F],
             SUM(CASE fcm.CollectionID WHEN 'ABC00062' THEN 1 ELSE 0 END) as [ABC00062]
          FROM
             dbo.v_FullCollectionMembership AS fcm
          WHERE
             fcm.CollectionID IN('ABC0001F','ABC00062')
          GROUP BY fcm.SiteCode) AS cnt ON so.SiteCode=cnt.SiteCode
ORDER BY so.PreOrder

drop table #SiteOrder


A bit more complicated again though.

Tom




Tom_Watson -> RE: Help with an SMS Report (6/24/2008 6:38:44 AM)

BTW.  Our DBAs just installed SQL 2005 on the server.

[:D]

Tom




jnelson993 -> RE: Help with an SMS Report (6/24/2008 10:35:02 AM)

<tearing up> that's just beautiful!

Another 8 years and perhaps you'll be able to upgrade to SQL 2008!




Tom_Watson -> RE: Help with an SMS Report (6/24/2008 11:38:44 AM)

Here's hoping.

PS.  Tried the sexual PIVOT report above, just for kicks.

Tom




pmurray -> RE: Help with an SMS Report (11/1/2008 9:58:39 AM)

Hello, I've been looking for precentage reports and the above has helped me to a point, I did the following for Microsoft Outlook 2007. I made a collection w/all outlook 2007, then made a collection of all systems with out outlook 2007.
==========================================================
SELECT 
cnt.D01002E7 AS [Non Outlook 2007],
cnt.D010018F AS [All Outlook 2007],
cnt.D010018F - cnt.D01002E7 AS [Difference],
CASE
   WHEN cnt.D010018F = 0 THEN NULL
   ELSE (cnt.D010018F - cnt.D01002E7)*100.0/cnt.D010018F
END AS [Percentage Of Outlook 2007 Installations]
FROM
(SELECT 
   SUM(CASE fcm.CollectionID WHEN 'D01002E7' THEN 1 ELSE 0 END) as [D01002E7],
   SUM(CASE fcm.CollectionID WHEN 'D010018F' THEN 1 ELSE 0 END) as [D010018F]
FROM
   dbo.v_FullCollectionMembership AS fcm
WHERE
   fcm.CollectionID IN('D01002E7','D010018F')
GROUP BY
   fcm.SiteCode) AS cnt
==========================================================

Worked great!! 

 Non Outlook 2007        All Outlook 2007                     Difference                       Percentage Of Outlook 2007 Installations 
      3710                              14431                                10721                                     74.291455893562 


However I need flexability.... I manage a primary site server of approx 18,000+ systems and growing with 30 diffrent OU's. I'd like to be able to make a percentage report on ANY software product with out having to make two collection for each software product, one with the SW product, one with out 30 times :)


Any suggestion?




jnelson993 -> RE: Help with an SMS Report (11/2/2008 5:38:45 PM)

The way I'd do it is maybe something like this:

1) Put the resourceIDs that have the software in question into a temp table...I'm not sure what you're using to determine if a product is installed, but you could use views like v_GS_SoftwareFile, v_Add_Remove_Programs or v_GS_Installed_Software to determine the software's existence on a machine.
2) LEFT JOIN the view called v_R_SYSTEM (or you could use v_GS_COMPUTER_SYSTEM if you're into that) to that temp table. 
3) Now, when left joined like that, if the resourceID of the temp table is NULL, that means the machines doesn't have the product, if it's NOT NULL, then the machine *has* the product, so you can use that to add up the resourceIDs.

Soooooo, to use this for a different product, just change the first query that pulls resourceIDs into the temp table so it pulls resourceIDs for whatever product you want.

A little suh-um like this:
-- PUT RESOURCEIDs THAT HAVE SOFTWARE INTO TEMP TABLE
SELECT
  ResourceID
INTO
  #tmpHasSoftware
FROM
  dbo.v_Add_Remove_Programs
WHERE
  DisplayName0 LIKE 'Microsoft O%utlook%'

-- LEFT JOIN TO THAT TEMP TABLE. IF tmp.RESOURCEID IS NULL, MEANS THAT
-- MACHINE DOESN'T HAVE THE PRODUCT, IF NOT NULL, MACHINE HAS THE PRODUCT
SELECT
  SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [MissingProduct],
  SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) AS [HasProduct],
  SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [Difference],
  CASE
     WHEN SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 END) = 0 THEN NULL
     ELSE (SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END)) * 100.0/SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END)
  END AS [Percentage of Product's Installations]
FROM
  dbo.v_R_System AS sys
  LEFT JOIN  #tmpHasSoftware AS tmp
     ON sys.resourceID = tmp.resourceID
WHERE
  sys.obsolete0 = 0
  AND sys.decommissioned0 = 0
  AND sys.client0 = 1

DROP TABLE #tmpHasSoftware





pmurray -> RE: Help with an SMS Report (11/3/2008 9:08:35 AM)

Hi jnelson993, Thanks for the responce.
 
I actually Poked around a little after I posted and stumbled across something Garth had on his website for patch's; http://smsug.ca/blogs/garth_jones/archive/2007/04/10/261.aspx
 
So I played around and came up with this,
 
Set Nocount OFF
Declare @Installed as int
Declare @Total as int
Declare @Per as Float

set @Installed = (SELECT SUM(CASE WHEN Displayname0 Like @productname THEN 1 ELSE 0 END) as 'Installed' FROM v_GS_ADD_REMOVE_PROGRAMS
JOIN v_FullCollectionMembership on v_GS_ADD_REMOVE_PROGRAMS.ResourceID=v_FullCollectionMembership.ResourceID
JOIN V_R_System on v_GS_ADD_REMOVE_PROGRAMS.ResourceID=V_R_System.ResourceID WHERE v_FullCollectionMembership.CollectionID = @collection AND

Active0='1')
set @Total = (SELECT count(*)FROM v_R_System JOIN v_FullCollectionMembership on v_R_System.ResourceID=v_FullCollectionMembership.ResourceID
WHERE v_FullCollectionMembership.CollectionID = @collection AND Active0='1')
set @Per = (select Sum(@installed*100/@total))

SELECT @total as 'Total Systems',
              @Installed as 'Total Installed',
            @Per as 'Percentage';

 
 
Now I have what I want, a prompt for displayname and prompt for collection.




pmurray -> RE: Help with an SMS Report (11/4/2008 9:00:26 PM)

John,

Actually I'm running into that same problem with the Office 2007 products as I am w/the other report your helping me with on the other thread.

In the section; 

set @Installed = (SELECT SUM(CASE WHEN Displayname0 Like @productname THEN 1 ELSE 0 END) as 'Installed'
              
FROM v_GS_ADD_REMOVE_PROGRAMS
           JOIN v_FullCollectionMembership on v_GS_ADD_REMOVE_PROGRAMS.ResourceID=v_FullCollectionMembership.ResourceID
           JOIN V_R_System on v_GS_ADD_REMOVE_PROGRAMS.ResourceID=V_R_System.ResourceID

WHERE
            v_FullCollectionMembership.CollectionID = @collection
           AND Active0='1')

Sooo you mentioned making a tmp table which I'm assuming you ment in the SQL database? I can't do that... corporate over in Europe won't allow us access :( so any suggestion?




jnelson993 -> RE: Help with an SMS Report (11/5/2008 10:47:42 AM)

Really?  I seriously doubt they have taken the steps necessary to prohibit the creation of temp tables...actually, I don't think that's even possible.  There are all kinds of built in SMS reports that build temporary tables.  Have you put the SQL query I gave you into a report and tried to run it?  It creates a temp table, uses it, and then deletes the temp table.  And that temp table only exists for a single user in a single session.  When the session is closed, the temp table is gone, even if you don't delete it manually.  This isn't really like creating a table of your own in the SMS DB that anyone can see and use.  THAT I'll bet they can lock down, but temp table creation...I find it hard to believe.  You'd have some reports that don't work.

For them to prohibit #temp table creation is like saying you can't use LIKE in your WHERE clause.  It's a part of the language and something any good SQL writer has to use at some point to make their code faster or easier to understand.  Now we CAN do this without a temp table, but why if we don't really have to.  Try this before you give up.

-- PUT RESOURCEIDs THAT HAVE SOFTWARE INTO TEMP TABLE
SELECT
  ResourceID
INTO
  #tmpHasSoftware

FROM
  dbo.v_Add_Remove_Programs
WHERE
  DisplayName0 LIKE 'Microsoft O%utlook%'


-- LEFT JOIN TO THAT TEMP TABLE. IF tmp.RESOURCEID IS NULL, MEANS THAT
-- MACHINE DOESN'T HAVE THE PRODUCT, IF NOT NULL, MACHINE HAS THE PRODUCT
SELECT
  SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [MissingProduct],
  SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) AS [HasProduct],
  SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [Difference],
  CASE
     WHEN SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 END) = 0 THEN NULL
     ELSE (SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END)) * 100.0/SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END)
  END AS [Percentage of Product's Installations]
FROM
  dbo.v_R_System AS sys
  LEFT JOIN  #tmpHasSoftware AS tmp
     ON sys.resourceID = tmp.resourceID
WHERE
  sys.obsolete0 = 0
  AND sys.decommissioned0 = 0
  AND sys.client0 = 1

DROP TABLE #tmpHasSoftware


Now, the reason why I think this would work and you're having troubles now is that the way I've written this query, it will only find unique resourceIDs that have a particular product.  So for those office products on your machines that show up twice (or more) because of those different productIDs, there will still be only one resourceID. 

Or, I suppose I *could* fix that trash that you got from Garth's site :)




pmurray -> RE: Help with an SMS Report (11/5/2008 12:13:11 PM)

quote:

ORIGINAL: jnelson993

Have you put the SQL query I gave you into a report and tried to run it? 



No I didn't I was under the impression I had to go into the SQL DB and do it. So now I tired it and the counts are way off.

I first tried, DisplayName0 LIKE 'Microsoft O%utlook%' like you suggested then I tried 'Microsoft Office Outlook 2007'and the counts are way off. Since no collection is being used it's querying every system so I pulled a report of all Microsoft Office Outlook 2007 and my counts is 17363

When I run the new report I get;

 MissingProduct     HasProduct   Difference  Percentage of Products Installations 
4172                       34268           30096          87.825376444496

So it's like triple it seems. 34268+4172 = 38440 and I have 21504 Active systems 




jnelson993 -> RE: Help with an SMS Report (11/5/2008 12:19:03 PM)

Well, I wasn't saying Microsoft O%utlook is the right thing to put in therer.  Because that will likely include all of the outlook related products or add-ons, not just outlook.  I was just using it as an example of how I'd do it.  You need to decide what the best product name is for what you're looking for.




pmurray -> RE: Help with an SMS Report (11/5/2008 12:36:09 PM)

But I tried the fully qualified name like I said

quote:

 
then I tried 'Microsoft Office Outlook 2007'and the counts are way off




jnelson993 -> RE: Help with an SMS Report (11/5/2008 1:20:12 PM)

Sorry, I missed that.

For some reason we missed the DISTINCT on the #temp table query.  Put SELECT DISTINCT on that top SELECT and it should resolve that..

BTW, what are you comparing the numbers to so that you KNOW the numbers are way off?




pmurray -> RE: Help with an SMS Report (11/5/2008 2:01:21 PM)

John,

GOT IT! the Distinct did it... OMG this is awsome!!!

I was comparing to a report I have by ProductID0 for outlook 2007 so I know the number where right.

Now 2 more question I have.

1. Could a ROUNDED statment be added to the percentage installed?
2. See attachment, what is the first row saying 0 records found? No matching records could be found. I'm thinking it has to do w/the part;

SELECT DISTINCT
ResourceID
INTO
#tmpHasSoftware
FROM
dbo.v_Add_Remove_Programs

WHERE
DisplayName0 LIKE @productname

 
 
 BTW I added @productname and @collectionID, it does the 0 records on both SQL statments, yours and your edited one i did w/the prompts

[image]local://upfiles/41072/7E2ACB804C9A41FDB88414F138730594.jpg[/image]




jnelson993 -> RE: Help with an SMS Report (11/5/2008 2:09:19 PM)

Oh, yeah, you just need to put

SET NOCOUNT ON

Before that first query.




jnelson993 -> RE: Help with an SMS Report (11/5/2008 2:26:01 PM)

Oh, and for the rounding, you can either just truncate it down to 2 decimal places by CAST ing it as a DECIMAL(5,2) (which won't round up/down, it will just drop off any precision after the 2nd place) or doing a ROUND to round it to two decimals and then CAST it.

So, convert this

CASE
    WHEN SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 END) = 0 THEN NULL
    ELSE SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END)) * 100.0/SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END)
END AS [Percentage of Product's Installations]


Into this

CASE
    WHEN SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 END) = 0 THEN NULL
    ELSE CAST(SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END)) * 100.0/SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) AS DECIMAL(5,2))
END AS [Percentage of Product's Installations]





pmurray -> RE: Help with an SMS Report (11/7/2008 5:54:11 AM)

Sweet, I'll give that a go.

I was wondering one more thing, how would I add a colum, All Active Systems.

So like..  All Active Systems     Has Product     Missing product     Difference     percentage of Installations




pmurray -> RE: Help with an SMS Report (11/7/2008 6:54:24 AM)

quote:

ORIGINAL: jnelson993

CASE
   WHEN SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 END) = 0 THEN NULL
   ELSE CAST(SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END)) * 100.0/SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) AS DECIMAL(5,2))
END AS [Percentage of Product's Installations]




So I tried this and I get a SQL syantax error, see attached.

Thank you

[image]local://upfiles/41072/3415217FCF4E4727B5FEDD04EE0A650F.jpg[/image]




jnelson993 -> RE: Help with an SMS Report (11/7/2008 2:03:11 PM)

Let me just paste the whole thing then. Oh, and I changed it to DECIMAL(19,2) to take into account those times when you have a really high percentage or if you have a really high negative percentage (I had an example of that when I tested it)

SET NOCOUNT ON

-- PUT RESOURCEIDs THAT HAVE SOFTWARE INTO TEMP TABLE
SELECT DISTINCT
ResourceID
INTO
#tmpHasSoftware
FROM
dbo.v_Add_Remove_Programs
WHERE
DisplayName0 LIKE @ProductName

-- LEFT JOIN TO THAT TEMP TABLE. IF tmp.RESOURCEID IS NULL, MEANS THAT
-- MACHINE DOESN'T HAVE THE PRODUCT, IF NOT NULL, MACHINE HAS THE PRODUCT
SELECT
SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [MissingProduct],
SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) AS [HasProduct],
SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [Difference],
CAST(ROUND((CASE
                WHEN SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 END) = 0 THEN NULL
                ELSE (SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END)) * 100.0/SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END)
             END),2) AS DECIMAL(19,2)) AS [Percentage of Product's Installations]
FROM
dbo.v_R_System AS sys
LEFT JOIN  #tmpHasSoftware AS tmp
    ON sys.resourceID = tmp.resourceID
WHERE
sys.obsolete0 = 0
AND sys.decommissioned0 = 0
AND sys.client0 = 1

DROP TABLE #tmpHasSoftware







pmurray -> RE: Help with an SMS Report (11/7/2008 9:23:48 PM)

Hi John,

I tried it out and it rounded out the percentage, thank you once again!

However it's funny you mentioned the high negative, I was going to ask you about that. However in trying the new sql statment I still got a weird percentage. I dont have the data right now but will get it posted by Monday.




pmurray -> RE: Help with an SMS Report (11/8/2008 7:27:58 AM)

Is it Monday already? :)

Attached is a screen shot of three reports, the first two I really don't understand why the percentage is off because "has product" is higher than "missing product". I'm leaning toward the ® symbol is causing the calculation to be off?

The third report is on %creative% and you'll see the percentage is in the negtive.

The only change I did to the sql was add the prompt for a collectionID

LEFT JOIN  #tmpHasSoftware AS tmp
   ON sys.resourceID = tmp.resourceID

JOIN v_FullCollectionMembership fcm
    ON sys.resourceID = fcm.resourceID

WHERE
sys.obsolete0 = 0
AND sys.decommissioned0 = 0
AND sys.client0 = 1
AND fcm.collectionID = @collection
DROP TABLE #tmpHasSoftware;

quote:

ORIGINAL: jnelson993

Let me just paste the whole thing then. Oh, and I changed it to DECIMAL(19,2) to take into account those times when you have a really high percentage or if you have a really high negative percentage (I had an example of that when I tested it)

SET NOCOUNT ON

-- PUT RESOURCEIDs THAT HAVE SOFTWARE INTO TEMP TABLE
SELECT DISTINCT
ResourceID
INTO
#tmpHasSoftware
FROM
dbo.v_Add_Remove_Programs
WHERE
DisplayName0 LIKE @ProductName

-- LEFT JOIN TO THAT TEMP TABLE. IF tmp.RESOURCEID IS NULL, MEANS THAT
-- MACHINE DOESN'T HAVE THE PRODUCT, IF NOT NULL, MACHINE HAS THE PRODUCT
SELECT
SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [MissingProduct],
SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) AS [HasProduct],
SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END) AS [Difference],
CAST(ROUND((CASE
               WHEN SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 END) = 0 THEN NULL
               ELSE (SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) - SUM(CASE WHEN tmp.resourceID IS NULL THEN 1 ELSE 0 END)) * 100.0/SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END)
            END),2) AS DECIMAL(19,2)) AS [Percentage of Product's Installations]
FROM
dbo.v_R_System AS sys
LEFT JOIN  #tmpHasSoftware AS tmp
   ON sys.resourceID = tmp.resourceID
WHERE
sys.obsolete0 = 0
AND sys.decommissioned0 = 0
AND sys.client0 = 1

DROP TABLE #tmpHasSoftware






[image]local://upfiles/41072/E4192D677E10428F904F422F12E12CA2.jpg[/image]




pmurray -> RE: Help with an SMS Report (11/10/2008 3:45:51 PM)

**Bump**

John,

Any ideas?




jnelson993 -> RE: Help with an SMS Report (11/11/2008 5:39:34 PM)

You know, Garth and I were chatting, and I like his way of doing it better.  When I wrote my code, I just tried to make something easy to understand which more or less mimicked what you did.  I chose temp table, which for certain things can be a fine way of temporarily storing things while you process other things.   In this case though, there's a small cost increase because temp table transactions are logged, which means they're written to disk temporarily.  His method of selecting counts into variables first and then just selecting from those doesn't involve any logged transaction and thus SQL can spit it out with slightly smaller cost and quicker response (cost 50/time 10ms vs cost 40/time 7ms).  Now, both of these are only marginally different, but I always welcome improvement, and leaner IS better.

declare @ProductName varchar(250)
declare @Has BigInt
declare @Missing BigInt
Declare @Total BigInt

set @ProductName = 'Adobe Flash Player ActiveX'

SET NOCOUNT ON

-- PUT RESOURCEIDs THAT HAVE SOFTWARE INTO TEMP TABLE
Set @Has = (SELECT DISTINCT count(resourceID) FROM dbo.v_Add_Remove_Programs WHERE DisplayName0 LIKE @ProductName)
Set @Total = (SELECT DISTINCT count(resourceID) FROM dbo.v_GS_COMPUTER_SYSTEM )
Set @missing = (select sum(@total - @has))


Select
   @Missing as 'Missing',
   @Has as 'Installed',
   @Total as 'Total',
   sum((@has * 100) / @total) as '%'





jnelson993 -> RE: Help with an SMS Report (11/11/2008 6:53:58 PM)

OK, now I'm rethinking this again.  That version doesn't have the DISTINCT in the right place, making less work for the SQL engine than it should have. 

It should be
  SELECT COUNT(DISTINCT ResourceID)...
instead of
  SELECT DISTINCT COUNT(ResourceID)...

The difference is, you want to count the distinct resourceIDs, you don't want a distinct overall count because there *IS* only one distinct count.  When you do it that way, now the cost is roughly the same as mine and the difference is negligible. 

Next, the @HAS number isn't removing obsolete or decommissioned records, so that number is likely too high, especially if you have a large environment with lots of decommissioned or obsolete records.

Then I'd change the SUM at the end to round properly, and a couple other things...

OK, gimme a few, I've gotta rewrite this thing, but I've got supper with the family first.




pmurray -> RE: Help with an SMS Report (11/11/2008 8:08:07 PM)

I truly appreciate this John and I'm glad to see your talking to Garth.

-Paul


quote:

ORIGINAL: jnelson993

OK, now I'm rethinking this again.  That version doesn't have the DISTINCT in the right place, making less work for the SQL engine than it should have. 

It should be
SELECT COUNT(DISTINCT ResourceID)...
instead of
SELECT DISTINCT COUNT(ResourceID)...

The difference is, you want to count the distinct resourceIDs, you don't want a distinct overall count because there *IS* only one distinct count.  When you do it that way, now the cost is roughly the same as mine and the difference is negligible. 

Next, the @HAS number isn't removing obsolete or decommissioned records, so that number is likely too high, especially if you have a large environment with lots of decommissioned or obsolete records.

Then I'd change the SUM at the end to round properly, and a couple other things...

OK, gimme a few, I've gotta rewrite this thing, but I've got supper with the family first.





jnelson993 -> RE: Help with an SMS Report (11/11/2008 9:53:24 PM)

Oh, one last thing, I think there's some confusion on what the % is you're trying to display...do you want
1) the percent of total machines that HAVE the product
example: 10 machines total, 8 have the product, 2 missing, percent should be 80

2) the percent of total machines that are MISSING the product
example: 10 machines total, 8 have the product, 2 missing, percent should be 20

3) something else?




pmurray -> RE: Help with an SMS Report (11/11/2008 10:03:42 PM)

Option 1 please; 10 machines total, 8 have the product, 2 missing, percent should be 80

Thanks

quote:

ORIGINAL: jnelson993

Oh, one last thing, I think there's some confusion on what the % is you're trying to display...do you want
1) the percent of total machines that HAVE the product
example: 10 machines total, 8 have the product, 2 missing, percent should be 80

2) the percent of total machines that are MISSING the product
example: 10 machines total, 8 have the product, 2 missing, percent should be 20

3) something else?





jnelson993 -> RE: Help with an SMS Report (11/12/2008 1:39:42 AM)


OK, do you have SQL 2005?  I put a few minutes of thought into this and instead of a #tmp table, I'd like to use the sexy new Common Table Expressions (CTE) available with SQL 2005+. 

--THESE FIRST TWO LINES ARE JUST SO YOU CAN RUN THIS FROM
--WITHIN SQL MANAGEMENT STUDIO OR SOMETHING TO TEST
declare @ProductName varchar(250);
set @ProductName = 'Adobe Flash Player ActiveX';


-- USE COMMON TABLE EXPRESSION (CTE) TO ACT KIND OF LIKE A TEMP TABLE
-- THIS WILL HOLD THE RESOURCEIDs FOR MACHINES THAT HAVE THE PRODUCT
WITH tmpHasSoftware (ResourceID) AS (
  SELECT DISTINCT
     ResourceID
  FROM
     dbo.v_Add_Remove_Programs
  WHERE
     DisplayName0 LIKE @ProductName
)
--NOW SELECT FROM THE CTE LIKE IT WAS A TEMP TABLE
SELECT
  TotalMachines,
  MissingProduct,
  HasProduct,
  ABS(HasProduct - MissingProduct) AS 'Difference',
  CAST(ROUND((HasProduct * 100) / (TotalMachines + .00000000000001),2) AS DECIMAL(19,2)) AS 'Percent Having Product'
FROM
(SELECT
     SUM(CASE WHEN tmp.ResourceID IS NULL THEN 1 ELSE 0 END) AS MissingProduct,
     SUM(CASE WHEN tmp.ResourceID IS NOT NULL THEN 1 ELSE 0 END) AS HasProduct,
     COUNT(sys.ResourceID) AS TotalMachines
  FROM
     dbo.v_R_System AS sys
     LEFT JOIN  tmpHasSoftware AS tmp
        ON sys.resourceID = tmp.resourceID
     INNER JOIN dbo.v_FullCollectionMembership AS fcm
        ON sys.resourceID = fcm.resourceID
       AND fcm.CollectionID = @Collection
  WHERE
     sys.obsolete0 = 0
     AND sys.decommissioned0 = 0
     AND sys.client0 = 1) AS tbl


Some notes about this:

Using ABS() to get the absolute value difference between the counts of having and missing the product. This will eliminate the negative difference.  Cuz really, does it matter if it's - or +?  You can remove the ABS if that doesn't suit you.

Adding .00000000000001 to the TotalMachines so that if the total count is 0 we don't get a divide by zero error when calculating the 'Percent Having Product'

I'm using v_R_System because for me I need it to remove decommissioned and obsolete records, but you'd be OK if you use v_GS_Computer_System like Garth likes to suggest.

Let me know if you need this explained any better.




pmurray -> RE: Help with an SMS Report (11/12/2008 5:55:52 AM)

Unfortunately where not on SQL 2005 :(

So how's about this, but work on that issue w/Office 2007 products with the dupe Displayname0 and if able to I liked the "difference" column but no big deal if it's to much.

Set Nocount OFF
Declare @Installed as int
Declare @Total as int
Declare @Per as Float

set @Installed = (SELECT SUM(CASE WHEN Displayname0 Like @productname THEN 1 ELSE 0 END) as 'Installed' FROM v_GS_ADD_REMOVE_PROGRAMS
JOIN v_FullCollectionMembership on v_GS_ADD_REMOVE_PROGRAMS.ResourceID=v_FullCollectionMembership.ResourceID
JOIN V_R_System on v_GS_ADD_REMOVE_PROGRAMS.ResourceID=V_R_System.ResourceID WHERE v_FullCollectionMembership.CollectionID = @collection AND

Active0='1')
set @Total = (SELECT count(*)FROM v_R_System JOIN v_FullCollectionMembership on v_R_System.ResourceID=v_FullCollectionMembership.ResourceID
WHERE v_FullCollectionMembership.CollectionID = @collection AND Active0='1')
set @Per = (select Sum(@installed*100/@total))

SELECT @total as 'Total Systems',
              @Installed as 'Total Installed',
          @Per as 'Percentage';




pmurray -> RE: Help with an SMS Report (11/12/2008 11:18:44 AM)

John,
I did a little tinkering and came up with this, let me know your thoughts. I still would like to work in "Difference" if possible.

declare @ProductName varchar(250)
declare @Has BigInt
declare @Missing BigInt
Declare @Total BigInt

set @ProductName = @product
SET NOCOUNT ON
-- PUT RESOURCEIDs THAT HAVE SOFTWARE INTO TEMP TABLE
Set @Has = (SELECT count(DISTINCT sys.resourceID) FROM v_Add_Remove_Programs arp
JOIN v_FullCollectionMembership fcm on arp.ResourceID=fcm.ResourceID
JOIN V_R_System sys on arp.ResourceID=sys.ResourceID WHERE fcm.CollectionID = @collection
      AND sys.Active0='1'
      AND arp.DisplayName0 LIKE @ProductName)

Set @Total = (SELECT count(DISTINCT sys.resourceID) FROM v_R_System sys JOIN v_FullCollectionMembership fcm on sys.ResourceID=fcm.ResourceID
WHERE fcm.CollectionID = @collection
      AND sys.Active0='1')


Set @missing = (select sum(@total - @has))

Select
  @Has as 'Product Installed',
  @Missing as 'Missing Product ',
  @Total as 'Total Systems',
  sum((@has * 100) / @total) as 'Percentage';




jnelson993 -> RE: Help with an SMS Report (11/12/2008 11:32:47 AM)

SQL 2000?  <Sigh>  How do I get sucked into this stuff?

OK, fine...let's take Garth's way and make it work.  First, you need nocount ON not OFF.  Second, that CASE statement isn't necessary in the @INSTALLED query.  Third, we want to count the distinct resourceIDs in the @Total section.  Third, the SUM in the @Per section isn't right and we need to handle the case when the @Total is 0 so we don't get a divide by zero error.  Lastly, we can add a difference column, no problem.

--these four lines are just so you can run it from SQL query analyzer
declare @Collection varchar(8);
set @Collection = '01000020'
declare @ProductName varchar(250);
set @ProductName = 'Adobe Flash Player ActiveX';


SET NOCOUNT ON
DECLARE @Installed AS INT
DECLARE @Total AS INT

SET @Installed = (SELECT
                   COUNT(DISTINCT ResourceID)
                 FROM  
                   v_GS_ADD_REMOVE_PROGRAMS AS arp
                 WHERE
                    arp.resourceID IN (SELECT resourceID
                                       FROM v_FullCollectionMembership
                                       WHERE collectionID = @Collection)
                    AND arp.resourceID IN (SELECT resourceID
                                           FROM V_R_System
                                           WHERE Active0 = 1))
SET @Total = (SELECT
               COUNT(DISTINCT ResourceID)
             FROM  
               v_R_System AS sys
             WHERE ResourceID IN (SELECT resourceID
                                  FROM v_FullCollectionMembership
                                  WHERE collectionID = @Collection)
               AND Active0 = '1')

SELECT
  @total     AS 'Total Systems',
  @Installed AS 'Total Installed',
  CAST(ROUND((@installed * 100 / (@total + .00000000000001)),2) AS DECIMAL(19,2))  AS 'Percent Having Product',
  @Total - @Installed AS 'Missing',
  ABS(@Installed - (@Total - @Installed)) AS 'Difference'


Hmm, the cost is even lower now.

Now, what's this about the Office 2007 stuff?  You want this solution to include proper counts of Office 2007 stuff where there are duplicate counts per machine because of the ProductID stuff?  This should work fine because of the COUNT(DISTINCT ResourceID).  Even if there are duplicate displayname's per machine, they will be eliminated by the DISTINCT.




pmurray -> RE: Help with an SMS Report (11/12/2008 12:43:02 PM)

Perfect perfect perfect!!! Allot faster to.

Once again I say Thank You! very much.

Sorry about SQL 2000, out of my control. We'll be getting SCCM Q1 next year but we are waiting on Europe central IT as there control freaks :) and won't let us do our own thing... so I'll have SQL 2005 then.

I've bee looking over your blog and I'm very interested in the PIVOT 2005 has to offer.


Again, thank you.. I'm very gratefully for all your efforts.




jnelson993 -> RE: Help with an SMS Report (11/12/2008 12:45:22 PM)

No biggie.  Half of this I worked on while on conference calls that were pointless.

Maybe you'd rate my post(s) if you found them helpful :)




Page: [1]

Valid CSS!




Forum Software © ASPPlayground.NET Advanced Edition 2.4.5 ANSI
0.609375