Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8132823
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T09:26:02+00:00 2026-06-06T09:26:02+00:00

I have a rather complicated (and very inefficient) way of getting utilisation from a

  • 0

I have a rather complicated (and very inefficient) way of getting utilisation from a large list of periods (Code below).

Currently I’m running this for a period of 8 weeks and it’s taking between 30 and 40 seconds to return data.

I need to run this regularly for periods of 6 months, 1 year and two years which will obviously take a massive amount of time.

Is there a smarter way to run this query to lower the number of table scans?
I have tried several ways of joining the data, all seem to return junk data.

I’ve tried to comment the code as much as I can but if anything is unclear let me know.

Table Sizes:

[Stock]        ~12,000 records
[Contitems]    ~90,000 records

Pseudocode for clarity:

For each week between Start and End:
    Get list of unique items active between dates (~12,000 rows)
        For each unique item
            Loop through ContItems table (~90,000 rows)
            Return matches
        Group
    Group
Return results

The Code

DECLARE @WEEKSTART DATETIME; -- Used to pass start of period to search
DECLARE @WEEKEND DATETIME; -- Used to pass end of period to search
DECLARE @DC DATETIME; -- Used to increment dates
DECLARE @INT INT; -- days to increment for each iteration (7 = weeks)
DECLARE @TBL TABLE(DT DATETIME, SG VARCHAR(20), SN VARCHAR(50), TT INT, US INT); -- Return table

SET @WEEKSTART = '2012-05-01'; -- Set start of period
SET @WEEKEND = '2012-06-25'; -- Set end of period
SET @DC = @WEEKSTART; -- Start counter at first date
SET @INT = 7; -- Set increment to weeks

WHILE (@DC < @WEEKEND) -- Loop through dates every [@INT] days (weeks)
BEGIN
    SET @DC = DATEADD(D,@INT,@DC); -- Add 7 days to the counter

        INSERT INTO @TBL (DT, SG, SN, TT, US) -- Insert results from subquery into return table
        SELECT @DC, SUB.GRPCODE, SubGrp.NAME, SUM(SUB.TOTSTK), SUM(USED)

        FROM
        (
        SELECT STK.GRPCODE, 1 AS TOTSTK, CASE (SELECT COUNT(*) 
                                                           FROM ContItems -- Contains list of hires with  a start and end date
                                                           WHERE STK.ITEMNO = ContItems.ITEMNO -- unique item reference
                                                           AND ContItems.DELDATE <= DATEADD(MS,-2,DATEADD(D,@INT,@DC)) -- Hires starting before end of week searching
                                                           AND (ContItems.DOCDATE#5 >= @DC -- Hires ending after start of week searching
                                                                OR ContItems.DOCDATE#5 = '1899-12-30 00:00:00.000')) -- Or hire is still active
                                                     WHEN 0 THEN 0 -- None found return zero
                                                     WHEN NULL THEN 0 -- NULL return zero
                                                     ELSE 1 END AS USED -- Otherwise return 1

        FROM Stock STK - List of unique items

        WHERE [UNIQUE] = 1 AND [TYPE] != 4 -- Business rules
        AND DATEPURCH < @DC AND (DATESOLD = '1899-12-30 00:00:00.000' OR DATESOLD > DATEADD(MS,-2,DATEADD(D,@INT,@DC))) -- Stock is valid between selected week
        ) SUB
        INNER JOIN SubGrp -- Used to get 'pretty' names
        ON SUB.GRPCODE = SubGrp.CODE
        GROUP BY SUB.GRPCODE, SubGrp.NAME






END

-- Next section gets data from temp table
SELECT SG, SN, SUM(TT) AS TOT, SUM(US) AS USED, CAST(SUM(US) AS FLOAT) / CAST(SUM(TT) AS FLOAT) AS UTIL
FROM @TBL
GROUP BY SG, SN
ORDER BY TOT DESC
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T09:26:05+00:00Added an answer on June 6, 2026 at 9:26 am

    I have two suggestions.

    First, rewrite the query to move the “select” statement from the case statement to the from clause:

    SELECT @DC, SUB.GRPCODE, SubGrp.NAME, SUM(SUB.TOTSTK), SUM(USED)
    FROM (SELECT STK.GRPCODE, 1 AS TOTSTK,
                  (CASE MAX(Contgrp.cnt) -- Or hire is still active
                         WHEN 0 THEN 0 -- None found return zero
                         WHEN NULL THEN 0 -- NULL return zero
                         ELSE 1
                    END) AS USED -- Otherwise return 1
            FROM Stock STK left outer join -- List of unique items
                 (SELECT itemno, COUNT(*) as cnt
                  FROM ContItems -- Contains list of hires with  a start and end date
                  WHERE ContItems.DELDATE <= DATEADD(MS,-2,DATEADD(D,@INT,@DC)) AND -- Hires starting before end of week searching
                         (ContItems.DOCDATE#5 >= @DC OR -- Hires ending after start of week searching
                          ContItems.DOCDATE#5 = '1899-12-30 00:00:00.000'
                         )
                  group by ITEMNO
                 ) ContGrp
                 on STK.ITEMNO = ContItems.ITEMNO
            WHERE [UNIQUE] = 1 AND [TYPE] != 4 AND -- Business rules
                  DATEPURCH < @DC AND (DATESOLD = '1899-12-30 00:00:00.000' OR DATESOLD > DATEADD(MS,-2,DATEADD(D,@INT,@DC))) -- Stock is valid between selected week
           ) SUB INNER JOIN SubGrp -- Used to get 'pretty' names
           ON SUB.GRPCODE = SubGrp.CODE
     GROUP BY SUB.GRPCODE, SubGrp.NAME 
    

    In doing this, I found a something suspicious. The case statement is operating at the level of “ItemNo”, but the grouping is by “GrpCode”. So, the “Count(*)” is really returning the sum at the group level. Is this what you intend?

    The second is to dispense with the WHILE loop, if you have multiple weeks. To do this, you just need to convert DatePurch to an appropriate week. However, if the code usually runs on just one or two weeks, this effort may not help very much.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a rather complicated lookup for an option. It comes from a separate
I have a (rather complicated) SQL statement where I select data from lots of
I have a rather complicated toolchain so prepare for a lengthy post until getting
I have a rather complicated setup which I have boiled down to the code
I have a rather complicated deploy setup for our Drupal site that is a
I have the following tricky problem: I have implemented a (rather complicated) class which
I have rather large project that uses ICU regex classes. Basically it might run
I have a rather large text corpus, of which I would like to check
I have a rather complicated Binding situation. I have a solution that I created
I have a rather complicated problem that I think boils down to the following.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.