Showing posts with label UNION ALL. Show all posts
Showing posts with label UNION ALL. Show all posts

Thursday, October 30, 2014

Payables Transaction Analysis - Unique Purchasing Transactions per day

Recently I answered a forum post by a user who wanted to know the number of transactions by module entered in a given day.  I authored a series of queries which allow a user to input a date and execute the query.

This query identifies the number of unique transactions in the appropriate tables (Open or Historical), and reveals the Number of Purchasing Transactions processed on a given day.

declare @Date as DATETIME
SET @Date = '04/12/2017'

/*Payables Transactions*/
Select SUM(PM_Trxs) PM_Trxs from (
Select COUNT(vchrnmbr) PM_Trxs FROM PM20000 where DOCDATE = @Date
Union All
Select COUNT(vchrnmbr) PM_Trxs FROM PM30200 where DOCDATE = @Date) a

Saturday, October 4, 2014

SQL Query Fundamentals (Part 2)

In my post SQL Query Fundamentals (Part 1) I covered a number of "fundamental" elements of SQL Query Design:

  1. Select statements
  2. Aliases
  3. Cases
  4. Casting
  5. Converting
  6. Table Joins
  7. Where Clauses
This post is intended to amplify and expand on these concepts to help resolve common problems with Query Design for practical purposes in concert with Dynamics GP.  

Dynamics GP is designed and built to support exceedingly large business with massive transaction loads.  Part of this architecture is the use of Work, Open and Historical tables to house data.  Typically Work Tables contain transactions being entered, which have not been posted.  Open tables contain transactions which have been posted in the current (Open) fiscal or calendar year.  Historical tables contain transactions from past (Closed) fiscal or calendar years.  

Dividing data into these categories and storing the data in different tables improves performance by ensuring users entering and accessing these various data types are not competing for the same resources.

As a consequence of this design and implementation, in order to produce a report, which contains all transaction data, you must combine the data from these various tables. This is not the same thing as a Join.  Typically, a join is intended to link tables together, so you can present additional data about the records you are interested in, like the address records associated with customer or vendor records.

When you desire to present data from two tables containing the same fields in a different state, like open vs. historical data, you do not use Left, Right, Inner or Outer Joins. You use Union statements.  In order to use a Union statement, the columns for the two tables must "constructively" match - there must be the same number of columns with the same data types.

Here's an example:


Now back to fundamentals.

First, you will note there is some Green text in the first line of this query.  This text has been commented out, and is functionally invisible to SQL. This can be accomplished by beginning a single line with two hyphens (--). Multiple lines can be commented by starting with /* and ending with */.  

I typically use comments liberally in queries, and you should develop this habit too. It is invaluable when coming back to a query later, especially much later, to know what you were thinking when you designed it. It is also helpful to comment the mechanisms, and purposes of joins, details about the tables and fields involved. This is especially useful in environments where you are part of a team.

You will notice the first column - Source, identifies the data source of a particular record. Using this simple feature is absolutely critical when presenting data from multiple tables. You simply quote the data source and alias the column.  In this case the sources were Inventory and Manufacturing tables which contain similar data. In other cases it may be Open and Historical. In either case, adding a column to denote the source, makes it easy to identify the source of the data.

The cost columns have a new Cast statement, which ensures they are presented in Money format (currency).

You may also notice there is a new kind of join in this statement - a Left Join. Left Joins are handy for adding fields from tables, where a value may or may not exist for the joining records. Inner Joins, require the presence of matching data, so using an inner join instead of a Left Join in this case, could restrict the records returned. If there is not a matching data point in the table you used a Left Join to connect, you will see NULL in the field. If you used an Inner Join, you would suppress the entire row, where a NULL value occurs.

Because this post is Dynamics GP specific I will explain the reason a left join was necessary. Since Dynamics GP can have a 66 character account number with up to 10 segments, and accounts are used in numerous places in Dynamics GP, Great Plains uses an Account Index instead of storing the whole account. This data is stored in the GL00100 table in the ACTINDX field (GL Master Records). More importantly, it is stored in the GL00105 table, which also includes the ACTNUMST field; Account Number String field. By Left Joining the GL00105 table, it is possible to include the actual account number in the query results.

Unlike JOINS, UNION statements connect tables without requiring the presence of matching values in fields. You could literally UNION queries of like fields in your Vendor and Customer tables. There are two types of UNION statements; UNION and UNION ALL.  UNION queries return unique values, and UNION ALL queries will include duplicate records, so if you want all the data, you'll need to use a UNION ALL statement.

In this case, Dynamics GP holds Standard Cost Revaluation Records in both Inventory and Manufacturing tables, because there are two tools to Revalue Standard Costs. In order to display pending Standard Cost changes, it is imperative to present the data from both sources.  


Finally, the last line in this query is an Order by statement.  Order by statements instruct the query to return the data in a particular order. Simply type Order by, and then specify the columns you want to sort your data by, separating them by commas.  The default sort order is Ascending. You can specify the sort order by typing ASC or DESC (short for Ascending and Descinding) after the column name.

Hopefully these posts have helped speed you on the way to learning SQL Query Fundamentals.