Identify Range from look up table

  • I have a query/report that I need to create that needs to look at the size of a company and based on that size apply different rules. I am sure that this is not the only query/report I'll need to do using this and I'm also not so sure that the size ranges won't be changed in the future. Given this, I'd like to store the size ranges in a lookup(global) table. That way, if the ranges ever change I can just alter them in that table and not in all of the queries/reports that use them. What I need to figure out is how to join the live table with the look up table.

    Specifically, here is what I have. The look up table would be:

    CREATE TABLE #gl_sizerange (

    glsid int IDENTITY(1,1) NOT NULL,

    lowsize int,

    highsize int,

    sizecat varchar(10),

    milestone varchar(25),

    days int

    ) ON [PRIMARY]

    INSERT into #gl_sizerange VALUES(1, 24, 'Small', 'Approach', 14)

    INSERT into #gl_sizerange VALUES(1, 24, 'Small', 'Interview', 14)

    INSERT into #gl_sizerange VALUES(1, 24, 'Small', 'Demonstrate', 21)

    INSERT into #gl_sizerange VALUES(1, 24, 'Small', 'Negotiate', 14)

    INSERT into #gl_sizerange VALUES(1, 24, 'Small', 'Close', 7)

    INSERT into #gl_sizerange VALUES(25, 99, 'Medium', 'Approach', 14)

    INSERT into #gl_sizerange VALUES(25, 99, 'Medium', 'Interview', 21)

    INSERT into #gl_sizerange VALUES(25, 99, 'Medium', 'Demonstrate', 21)

    INSERT into #gl_sizerange VALUES(25, 99, 'Medium', 'Negotiate', 14)

    INSERT into #gl_sizerange VALUES(25, 99, 'Medium', 'Close', 7)

    INSERT into #gl_sizerange VALUES(100, 499, 'Large', 'Approach', 14)

    INSERT into #gl_sizerange VALUES(100, 499, 'Large', 'Interview', 21)

    INSERT into #gl_sizerange VALUES(100, 499, 'Large', 'Demonstrate', 21)

    INSERT into #gl_sizerange VALUES(100, 499, 'Large', 'Negotiate', 14)

    INSERT into #gl_sizerange VALUES(100, 499, 'Large', 'Close', 7)

    INSERT into #gl_sizerange VALUES(500, 300000000, 'Super', 'Approach', 28)

    INSERT into #gl_sizerange VALUES(500, 300000000, 'Super', 'Interview', 35)

    INSERT into #gl_sizerange VALUES(500, 300000000, 'Super', 'Demonstrate', 28)

    INSERT into #gl_sizerange VALUES(500, 300000000, 'Super', 'Negotiate', 35)

    INSERT into #gl_sizerange VALUES(500, 300000000, 'Super', 'Close', 35)

    Then what I have is two more tables, one that indicates the size of the company and another that has the milestone contained within it and I will also calculate how long that milestone has been open and if it is longer than what is in the lookup table for that milestone and size range I need it returned in the report. Here are some quick sample table to represent that data (I've condensed the size and number of tables for the example):

    CREATE TABLE #en_entity (

    enid int NOT NULL,

    orgsize int,

    ) ON [PRIMARY]

    INSERT into #en_entity VALUES(1, 5)

    INSERT into #en_entity VALUES(2, 18)

    INSERT into #en_entity VALUES(3, 24)

    INSERT into #en_entity VALUES(4, 25)

    INSERT into #en_entity VALUES(5, 47)

    INSERT into #en_entity VALUES(6, 101)

    INSERT into #en_entity VALUES(7, 499)

    INSERT into #en_entity VALUES(8, 500)

    INSERT into #en_entity VALUES(9, 10000)

    INSERT into #en_entity VALUES(10, 567890)

    CREATE TABLE #op_opportunity (

    opid int NOT NULL,

    enid int NOT NULL,

    milestone varchar(25),

    daysopen int

    ) ON [PRIMARY]

    INSERT into #op_opportunity VALUES(1, 1, 'Approach', 5)

    INSERT into #op_opportunity VALUES(2, 2, 'Interview', 18)

    INSERT into #op_opportunity VALUES(3, 4, 'Negotiate', 24)

    INSERT into #op_opportunity VALUES(4, 7, 'Demonstrate', 25)

    INSERT into #op_opportunity VALUES(5, 7, 'Approach', 7)

    INSERT into #op_opportunity VALUES(6, 9, 'Close', 35)

    INSERT into #op_opportunity VALUES(7, 8, 'Close', 36)

    So, given the sample data, I would expect the results to return me the following opids from the #op_opportunity table because they don't comply with what is in the look up table based on milestone, size and days open: 2,3,4,7

  • our reporting DBA's usually write huge stored procedures with a lot of CASE statements for these things or multiple stored procedures and functions with CASE statements from the master calling each one based on the conditions

    most of them come from a dev background so everything is like OOP

  • See if this helps

    SELECT o.opid,o.enid,o.milestone,o.daysopen,

    e.orgsize,g.days,

    CASE WHEN o.daysopen > g.days THEN 'Not Comply' ELSE 'Comply' END

    FROM #op_opportunity o

    INNER JOIN #en_entity e ON e.enid=o.enid

    INNER JOIN #gl_sizerange g ON e.orgsize BETWEEN g.lowsize AND g.highsize AND g.milestone=o.milestone

    ____________________________________________________

    Deja View - The strange feeling that somewhere, sometime you've optimised this query before

    How to get the best help on a forum

    http://www.sqlservercentral.com/articles/Best+Practices/61537
  • Thanks Mark. For some other applications I may use your solution. For this one I ended up with this, which returns just the records that are out of compliance.

    SELECT *

    FROM #en_entity e JOIN #op_opportunity o ON e.enid = o.enid

    JOIN #gl_sizerange s ON o.milestone = s.milestone

    WHERE e.orgsize BETWEEN s.lowsize AND s.highsize

    AND o.daysopen > s.days

    ORDER BY e.enid

Viewing 4 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic. Login to reply