0

UPDATE: Now that I think about it, using MAX would just give me the latest version and the count numbers that were given for that latest version, not all counts and times added up for "version 10. Please let me know if there is a way around this so I can add up all counts and times for version 10.*

 use CM_CSA
 SELECT DISTINCT
    RS.Name0,
    MU.UserName,
    SF.FileName,
    SF.FileVersion as 'FileVersion',
    MUS.UsageCount as 'UsageCount', 
    MUS.UsageTime as 'UsageTime', 
    MUS.LastUsage as 'LastUsage'
 FROM 
    v_MeteredUser MU
    INNER JOIN (
        SELECT ResourceID,MeteredUserID,FileID,SUM(UsageCount) as 'UsageCount',SUM(UsageTime) as 'UsageTime',MAX(LastUsage) as 'LastUsage'
        FROM v_MonthlyUsageSummary 
        GROUP BY ResourceID,MeteredUserID,FileID
    ) MUS ON MU.MeteredUserID = MUS.MeteredUserID
    INNER JOIN (
        SELECT ResourceID,FileName,FileID,MAX(FileVersion) as 'FileVersion'
        FROM v_GS_SoftwareFile
        GROUP BY FileVersion,ResourceID,FileName,FileID
    ) SF ON MUS.FileID = SF.FileID
    INNER JOIN v_R_System rs on rs.ResourceID = MUS.ResourceID
 WHERE
    SF.FileName like '%acrobat%'
    and MU.UserName like '%jeffrey.toy%'
 ORDER BY MU.UserName, SF.FileName, MUS.LastUsage

The results I"m getting are below. Obviously, the MAX function for FileVersion is not working since there are multiple decimal places. How do I fix this so that I can only show Acrobat version 10 only (no decimal points) so that it adds up all 4 columns. Results:

    Name0        UserName   FileName    FileVersion UsageCount  UsageTime   LastUsage
    GLDLBAE016992   jeffrey.toy Acrobat.exe 10.1.5.33   3   498 6/4/2013
    GLDLBAE016992   jeffrey.toy Acrobat.exe 10.1.7.27   13  6458    9/8/2013
    GLDLBAE016992   jeffrey.toy Acrobat.exe 10.1.8.24   39  2301736 2/18/2014
    GLDLBAE016992   jeffrey.toy Acrobat.exe 10.1.10.18  1   15  6/15/2014
    GLDLBAE016992   jeffrey.toy Acrobat.exe 10.1.9.22   34  818966  6/15/2014
user3711442
  • 213
  • 2
  • 6
  • 15
  • What database is this on? You can't treat it as a string. – OldProgrammer Jun 20 '14 at 22:10
  • How is the `FileVersion` column defined? – Air Jun 20 '14 at 22:15
  • SQL Server 2008 R2. I'm not sure how to convert it. Beginner with SQL. I would be happy with even multiplying the versions by 10,000 so that it shows as 101533, 101727, etc. Then I can use the MAX function and then use a CASE statement to just show "10". Any other recommendations would be great. – user3711442 Jun 20 '14 at 22:16
  • Yea, scaling the subversions and adding them somehow would do the trick. alas I am an Oracle guy. Hope someone can answer. – OldProgrammer Jun 20 '14 at 22:18
  • You can't just "multiply" the versions - you need `1.2.3` to come before `1.1.10`. It's not clear to me exactly what your desired result is, though - do you want to see all records with version 10.x.x.x? Or only the "highest" of those? – Air Jun 20 '14 at 22:18
  • I'm confused. You want the actual max version? Or do you just want all those to show 10 in your example? – SQLChao Jun 20 '14 at 22:20
  • I thought if I could store it as a small integer, then it wouldn't use the decimal points if I multiplied by a large number. However, I'm not sure how to do that. If anyone has any other suggestions for truncating this so that it only shows one version of 10, that would be very helpful. – user3711442 Jun 20 '14 at 22:20
  • 1
    I don't necesarilly need a MAX version. I just want there to be one row instead of 5. I want all counts from all versions to be added up and have it show as Version 10 in a single row. Every time a patch is installed, it creates a separate count and I want to combine all of those counts since it is all Acrobat 10. – user3711442 Jun 20 '14 at 22:21

3 Answers3

0

Ok changing my answer as it wasn't helping you. At this point since you have a query that gets you the results and you just need to group them, how about putting the whole thing as another select such as below. The one extra bit I had to do was add the piece to get "10" which was in my original answer.

SELECT Name0,
UserName,
FileName,
FileVersion,
SUM(UsageCount)
SUM(UsageTime)
MAX(LastUsage)
    (SELECT DISTINCT
     RS.Name0,
     MU.UserName,
     SF.FileName,
     left(FileVersion,CHARINDEX('.', FileVersion, 1) - 1) as 'FileVersion',
     MUS.UsageCount as 'UsageCount', 
     MUS.UsageTime as 'UsageTime', 
     MUS.LastUsage as 'LastUsage'
  FROM 
    v_MeteredUser MU
    INNER JOIN (
        SELECT ResourceID,MeteredUserID,FileID,SUM(UsageCount) as 'UsageCount',SUM(UsageTime) as     'UsageTime',MAX(LastUsage) as 'LastUsage'
        FROM v_MonthlyUsageSummary 
        GROUP BY ResourceID,MeteredUserID,FileID
    ) MUS ON MU.MeteredUserID = MUS.MeteredUserID
    INNER JOIN (
        SELECT ResourceID,FileName,FileID,MAX(FileVersion) as 'FileVersion'
        FROM v_GS_SoftwareFile
        GROUP BY FileVersion,ResourceID,FileName,FileID
    ) SF ON MUS.FileID = SF.FileID
    INNER JOIN v_R_System rs on rs.ResourceID = MUS.ResourceID) a
WHERE
  FileName like '%acrobat%'
  and UserName like '%jeffrey.toy%'
GROUP BY Name0,
  UserName,
  FileName,
  FileVersion
SQLChao
  • 7,709
  • 1
  • 17
  • 32
  • Unfortunately, I still have 5 rows showing up. They are all showing Version "10" now, but I still need to have only 1 row display. I previously had 10+ rows, but once I added the SUM functions for count and time and then MAX for last usage, it brought it down to 5. Now I need it down to 1 row for Acrobat 10 where all counts and times are summed up and last usage is shown. – user3711442 Jun 20 '14 at 22:26
  • @user3711442 How would you choose which `LastUsage` value to show? Most recent date? – Air Jun 20 '14 at 22:28
  • MAX(LastUsage) returns the most recent date. – user3711442 Jun 20 '14 at 22:30
  • @user3711442 I think you need to add this same logic in your GROUP BY clause. Unfortunately I just left the house so I can't test. – SQLChao Jun 20 '14 at 22:33
0

You are selecting max(fileversion) and then grouping by Fileversion in your derived table (SF). take fileversion out of your grouping and this should eliminate the row multiplication. Borrowing from the other answer, use max(left(FileVersion,CHARINDEX('.', FileVersion, 1) - 1)) and remove filegversion from the grouping. This should give you one row.

Jaaz Cole
  • 3,119
  • 1
  • 15
  • 20
  • Even after removing FileVersion from grouping, I get the same results. I figured out that MAX wouldn't work for me anyways as it will only show version 10.1.9.22 and the counts for that specific version instead of adding counts from all 5 rows to make 1 row for "Acrobat 10." – user3711442 Jun 20 '14 at 22:53
  • Still no luck. I either get 5 rows or I get 1 row with the results from that row. I need the other columns added. – user3711442 Jun 20 '14 at 23:09
0

Okay, based on this comment:

I want all counts from all versions to be added up and have it show as Version 10 in a single row. Every time a patch is installed, it creates a separate count and I want to combine all of those counts since it is all Acrobat 10.

There are a few things you need to do:

  1. Transform FileVersion so that A.B.C.D is treated as simply A;
  2. GROUP BY that A value;
  3. Aggregate the fields UsageCount, UsageTime, and LastUsage one more time in your outer SELECT statement.

This can be done, with the caveat that it is not generally performant to GROUP BY a calculated value, since the grouping can't be performed using an index.

There are several different options for the first step; unfortunately, in the case of SQL Server, a built-in string split function is not one of them. You could write a user-defined function, or use @JChao's suggestion; there's also an interesting hack suggested in another question that makes use of PARSENAME():

PARSENAME('10.1.5.33', 4)  -- returns '10'

The limitations of PARSEDNAME() for this purpose are many - it can only recognize . as the separator, it counts elements right-to-left (indexed from 1), it only outputs at most 4 elements, and it doesn't give the integer output you want. If you're confident you won't have to deal with separators other than ., or more than three instances of the separator, you could work out a way to always get the left-most element using e.g. COALESCE()... but that's a lot of contortion, so let's KISS for now, and you can use whatever function works for you in the end. Assuming the version format is always A.B.C.D, you can use:

PARSENAME(FileVersion, 4) AS 'FileVersion'

Now, this is a calculated value, so when you go to GROUP BY you can't just use the alias; you have to provide the calculation expression (or throw your entire query into a subquery... let's not go crazy here):

GROUP BY PARSENAME(FileVersion, 4)

I'm not sure what each of these joins is really doing for you here, but based on the result say you say your original query is giving you, try this out and see if it does what you're looking for:

SELECT DISTINCT
    RS.Name0,
    MU.UserName,
    SF.FileName,
    PARSENAME(SF.FileVersion, 4) as 'FileVersion',
    SUM(MUS.UsageCount) as 'UsageCount', 
    SUM(MUS.UsageTime) as 'UsageTime', 
    MAX(MUS.LastUsage) as 'LastUsage'
 FROM 
    v_MeteredUser MU
    INNER JOIN (SELECT ResourceID, MeteredUserID, FileID, SUM(UsageCount) AS 'UsageCount',
                       SUM(UsageTime) AS 'UsageTime', MAX(LastUsage) AS 'LastUsage'
                FROM v_MonthlyUsageSummary 
                GROUP BY ResourceID, MeteredUserID, FileID
                ) MUS ON MU.MeteredUserID = MUS.MeteredUserID
    INNER JOIN (SELECT ResourceID, FileName, FileID, MAX(FileVersion) as 'FileVersion'
                FROM v_GS_SoftwareFile
                GROUP BY FileVersion, ResourceID, FileName, FileID
                ) SF ON MUS.FileID = SF.FileID
    INNER JOIN v_R_System rs ON rs.ResourceID = MUS.ResourceID
 WHERE
    SF.FileName like '%acrobat%'
    and MU.UserName like '%jeffrey.toy%'
 GROUP BY RS.Name0, MU.UserName, SF.FileName, PARSENAME(FileVersion, 4)
 ORDER BY MU.UserName, SF.FileName, MUS.LastUsage

In the future this sort of thing would be much easier if you stored the version data more atomically, i.e. as separate major, minor, patch, build fields; but I understand that versioning formats vary and you may not be able to fit your data into one consistent format, so perhaps that's just not happening.

Community
  • 1
  • 1
Air
  • 8,274
  • 2
  • 53
  • 88
  • I received the error: "Column 'v_R_System.Name0' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause." I will try to look further into your comment and see what I can do. If you know what I can change based on the error, please let me know. – user3711442 Jun 20 '14 at 23:20
  • @user3711442 Of course - my mistake. You are actually grouping on the name, filename, and username in addition to the version. See my update. – Air Jun 20 '14 at 23:22
  • @user3711442 I would double check the subquery aliased `SF` as well though, if I were you - selecting `MAX(FileVersion)` while grouping on `FileVersion` probably isn't what you mean to do. It's not clear at first glance which you want, though. – Air Jun 20 '14 at 23:29
  • I'm not quite sure what PARSENAME does, but we are now down to one row to show one Acrobat 10. However, the count and time columns are incorrect. The single row should show the SUM of the 5 rows I have above (3, 13, 39, 1, and 34). The single count column now shows "15402." I'm not sure where it's getting the extra info from, but ti's not from the 5 instances of Acrobat 10.* that were showing up. However, the "Last Usage" column does appear to be correct (same Last Usage that is showing above with my first query). – user3711442 Jun 21 '14 at 00:41