823.TXT
     =====================================================================
     Calculate Total Sales by Month
     =====================================================================
     PRODUCT:   R:BASE                 VERSION:  4.5 or Higher
     =====================================================================
     CATALOG:   Programming in R:BASE  AREA   :  Logic & Data Manipulation
     =====================================================================
 
     Sometimes, a question can't be answered by a single SELECT command.
     In these situations, views on views are used to quickly return an
     answer. Don't spend hours trying to use a single command when using
     an intermediate view can make the process simple and fast.
 
     Grouping data by month is one situation where an intermediate view
     makes the query simpler. It's easy to find the month from a DATE data
     type column using the IMON SuperMath function, but you can't group by
     a function, only a column. So even though you can extract the month,
     you still need to group the data by the actual date, which groups the
     data by day, not by month. Instead, create a view that includes all
     the relevant columns and instead of the date column, includes just
     the month. Then the final query, grouping the data by month, is done
     using the view instead of the actual table.
 
     For example, you want to create a report listing companies with total
     sales of over $200,000 in one month. The table storing order
     information, Transmaster, contains a date column, transdate, but not
     a separate column for the month. The following steps show how to
     create the view and select the desired data.
 
     1. Create a view that lists the customer number, the month, and the
     sales amount for each transaction. Other columns could be included in
     the view. The view is created using optional column names since we are
     selecting an expression.
 
     CREATE VIEW sales (custid, month, amount) AS +
     SELECT custid, IMON(transdate), invoicetotal +
     FROM transmaster
 
     The IMON function returns the integer representation of the month
     (January = 1). You could also use the TMON function which returns a
     3-character text representation of the month (January = Jan).
 
     2. Select from the view to verify the data.
 
     SELECT * FROM sales ORDER BY month, custid
 
     custid     month      amount
     ---------- ---------- ---------------
            100          7      $29,457.00
            100          7      $87,280.00
            101          7      $95,462.50
            101          7      $32,730.00
            102          7      $31,775.37
            103          7     $166,104.75
            103          7      $45,822.00
            104          7      $68,733.00
            105          7     $182,469.75
            105          7      $10,910.00
            106          7     $153,067.30
            101          8      $24,547.50
            101          8     $192,016.00
            101          8      $31,639.00
            102          8     $169,650.50
            104          8      $61,368.75
            104          8     $104,190.50
            107          8     $118,646.25
            107          8      $81,006.75
 
     Each customer sale is now associated with just the month of the sale,
     not the year and day.
 
     3. Use a GROUP BY clause to see the total sales by customer by month.
     Some customers have sales in two months, some customers have sales in
     just one month.
 
     SELECT custid, month, SUM(amount) FROM sales GROUP BY custid, month
 
      custid     month      SUM (amount)
      ---------- ---------- ---------------
             100          7     $116,737.00
             101          7     $128,192.50
             101          8     $248,202.50
             102          7      $31,775.37
             102          8     $169,650.50
             103          7     $211,926.75
             104          7      $68,733.00
             104          8     $165,559.25
             105          7     $193,379.75
             106          7     $153,067.30
             107          8     $199,653.00
 
     4. The HAVING clause is then added to the command to restrict the
     results to those customers whose sales for a single month are over
     $200,000.
 
     SELECT custid, month, SUM(amount) FROM sales GROUP BY custid, month
     HAVING SUM(amount) > $200000
 
      custid     month      SUM (amount)
      ---------- ---------- ---------------
             101          8     $248,202.50
             103          7     $211,926.75
 
     The HAVING clause is used to qualify groups of rows. Because it looks
     at a group of rows, the aggregate functions can be used to put
     conditions on the group. This SELECT command lists the customer ID,
     the month, and the total sales for each customer, but only if the
     total sales are over $200,000.00 for one month.
 
     5. To see the company name in addition to the data in the view, create
     a multi-table SELECT command using the view and the customer table.
 
     SELECT custid, MAX(company), month, SUM(amount) FROM sales, customer
     WHERE sales.custid = customer.custid GROUP BY custid, month HAVING
     SUM(amount) > $200000
 
      custid     MAX (company)             month     SUM (amount)
      ---------- ------------------------- ------- --------------
             101 Computer Distributors Inc.      8    $248,202.50
             103 Computer Mountain Inc.          7    $211,926.75
 
     We use the aggregate function MAX on the company column so it doesn't
     need to be added to the GROUP BY clause. It doesn't change the
     results because there is only one company name for each customer ID.
 
     The query can also be used as a sub-SELECT in a WHERE clause. You can
     think of the query as returning a list of customer ID's. This list of
     customer ID's can then be compared to the customer ID column in other
     tables. You can use the sub-SELECT with an EDIT USING or a PRINT
     command as well as with another SELECT command.
 
     SELECT custid, company, transid, transdate, invoicetotal+
     FROM customer t1, Transmaster t2
     WHERE custid IN (SELECT custid FROM sales GROUP BY custid,+
     month HAVING SUM(amount) > $200000) ORDER BY custid
 
     EDIT USING tranform WHERE custid IN (SELECT custid FROM+
     sales GROUP BY custid, month HAVING SUM(amount) > $200000)+
     ORDER BY custid
 
     PRINT goodcust WHERE custid IN (SELECT custid FROM sales+
     GROUP BY custid, month HAVING SUM(amount) > $200000)
 
     Don't limit yourself by thinking you can only use one SELECT
     command. With views you can combine SELECT commands to return a
     variety of results. Views do not limit your data, but rather expand
     the possibilities.