AFHood Group Blog The thoughtless yammerings of marketing junkies..

14Jan/110

SQL tip – Inner join shorthand with USING

We write a LOT of SQL here and although SQL is a powerful database language, it can be tedious. So here is one tip for shortening all that typing.

Typical join sytax:

select some_columns

from one_table join another_table on one_table.column_1 = another_table.column_1 and one_table.column_2=another_table.column_2

where some_column > someother_column ;

Not too bad, right?

In order for this tip to work, you must be joining on columns with the same name (ie. column_1 and column_2 have the same name in both tables).

Here it is:

select some_columns

from one_table join another_table using (column_1, column_2)

where some_column > someother_column ;

Now, in our example it's not a drastic difference in coding, but as any programmer knows, this shorthand example doesn't accurately represent the real world. So give this syntax a try on your next project and let us know if it doesn't save you some typing.

11Nov/100

SAS / Teradata Fastexport – dbsliceparm = all

Fastexport is the fastest way to get large data out of teradata. Fastexport utilizes multiple connections to deliver data and therefore speeding up the transfer of data between Teradata and SAS.

Here are a few examples of fastexport.

/* libname statement*/

libname teradb  teradata username=&un password=&pw dbsliceparm=all;

/* explicit sql */

proc sql;

connect to teradata(username=&un password=&pw dbsliceparm=all);

<SQL STATMENT>

quit;run;

How do you know if fastexport was used?

Use this option:

options sastrace=',,,d' sastraceloc=saslog;

If it is working, you should see something in your log like:

Select was processed with fastexport.

There are many other factors that come into play if fastexport doesn't work. Check the requirements on the SAS support page for troubleshooting.

4Nov/100

4 tips for integrating CRM technology

If you have worked with marketing technologies for any length of time, you've encountered this problem. How can we integrate our CRM with the rest of our organization? How does CRM interact with our call center, website, applications, database, loyalty system, etc., etc.

We've been there.

Throughout our travels, we've picked up a few tips. Hopefully they'll help you.

  1. Tight integration is dangerous. Just don't do it. - Marketing technology changes faster than fashion. Today's latest and greatest is quickly replaced with tomorrow's new market maker.
  2. Integrate through marketing concepts not technical application specs. - Abstracting technologies through the use marketing concepts like 'campaign', 'offer', 'contact history', 'registration', 'enrollment', etc. Define what these mean for the organization and build a data structure flexible enough for all applications to contribute to those concepts.
  3. Databases and services are the lifeline. - Long term success hinges on ease of use and flexibility. Simple services allow for plug and play scenarios. Well designed databases create environments that record interrelated transactions based on their role or concept. This makes business people happy. They can measure, analyze and predict without spending precious hours compiling, cleaning, and organizing data.
  4. Think replaceable. - Always remember that what you are adding to your technology stack could be replaced in a year and you will need to re-integrate something else. How much of your current work will be thrown away? Minimize the one-time development and maximize your efficiency and cost savings to the organization over the long haul.

We like to think we aren't integrating technology. We are simply making all of our applications play nicely together.

There is much more to this topic, but these 4 tips can minimize your stress for ears to come.

6Jul/090

SAS fastload to Teradata

NOTE - SAS changed the default settings for fastload in SAS9. This has not been an improvement. SAS has documented how to change the setting back to the previous default in their note here... click here

The fastload facility for Teradata through SAS ACCESS is one that every analyst loading data into Teradata should be aware of. This tool allows you to pump data from SAS to Teradata in the quickest manner. The target table must be empty. There are other limitations as well, but most are uncommon problems.

To use the fastload option, follow the example below (SAS9 and above may require more manual settings to see max performance):

data td_lib.empty_table (bulkload=YES);

set source_table;

run;

Another way...

proc append data=source_table

base=td_lib.empty_table

(bulkload=YES bl_log=append_err_output);

run;

If your organization uses Teradata and could use some help utilizing the full power of SAS with Teradata, we are available to assist you.

29Dec/080

Creating Dynamic Shell Scripts using SAS

Here is one for your collection. This one is a little out of the "basics" realm and into the wierd and unusual.

Let me begin by explaining what this is and what you may use it for. First, this is SAS's ability to write to a file and then execute that file in SAS or on the command line. For my examples, I will be using SAS on Unix. So we tell SAS to output to a file and then give the commands to execute that file.

So, you might ask, why would I use this? Well, my most recent real world example is a nightly refresh of a very large reporting structure. The architecture is as follows. There are a large number of standard reports/tablse that need to be refreshed. I have a SAS project that retrieves the most recent list of refreshes and builds a shell script for each. The code then executes the scripts 10 at a time until all are done. Each script it builds checks the load on the database to ensure we aren't killing it and that we can get a connection for the next round of reports. As the reports complete, we kick off the next round until all are refreshed. This allows the process to "spawn" processes and manage them in a way that is reasonable to the enterprise and database.

So, lets begin by talking about how you create a shell script in SAS. To do this, we will use a dataset in the following syntax:

data _null_;

file test_file.sh;

put "projects=( &proj_list )" ;

put "DATE=/usr/bin/date" ;

put "for num in ${projects[@]}" ;

put "do" ;

put 'echo "working on project number $num - `$DATE`" ' ;

put "done" ;

put 'echo "all work done!" ' ;

run;

After we have successfully created the file, we can now kick it off to run. On a side note, I like to add the output of the file to the current log.

filename kickoff pipe ". /test_file.sh &";

data _null_;

infile kickoff;

input;

put _infile_;

run;

The leading "." on the filename command tells Unix to execute the script regardless of its permissions. The "&" after the filename tells Unix to execute the command outside of this session or screen.

I hope this overly simplistic example is helpful. You can only imagine how complex this can get very quickly. It has been our experience that many organizations are exploiting this to build production systems with SAS. This functionality separates the SAS experts from the "analysts". Using this functionality makes in extremely important to document your code. As you begin to add variables and "include" statements, things get fuzzy very quickly.

If you have a code base that utilizes this functionality and you need assistance, please don't hesitate to let us know. We are ready to help support your organization.

19Dec/080

SAS Proc Import

First, there is no way I can include everything that you can do with proc import in one post. So let me cover a couple of simple examples. Let me begin by saying that Proc Import does exactly what it sounds like, it imports data into SAS. The availability of given options within Proc Import are solely based on the version of SAS and the packages/add-ons your have for it.

The most basic version of proc import is as follows:

proc import

out=new_dataset

file="some file in some directory (c:/this_directory/file.csv)"

dbms=DLM REPLACE

delimiter=',' ;

run;

Now, "out" signifies the name and location of the new dataset. "file" is the location and name of the incoming data. "dbms" is the type of import you are doing.

Available DBMS Specifications
Identifier Input Data Source Extension
ACCESS Microsoft Access database .MDB
DBF dBASE file .DBF
WK1 Lotus 1 spreadsheet .WK1
WK3 Lotus 3 spreadsheet .WK3
WK4 Lotus 4 spreadsheet .WK4
EXCEL Excel Version 4 or 5 spreadsheet .XLS
EXCEL4 Excel Version 4 spreadsheet .XLS
EXCEL5 Excel Version 5 spreadsheet .XLS
EXCEL97 Excel 97 spreadsheet .XLS
DLM delimited file (default delimiter is a blank) .*
CSV delimited file (comma-separated values) .CSV
TAB delimited file (tab-delimited values) .TXT

The "delimiter" is specific to the DLM type. It tells SAS what the delimiter is within the incoming data.

"REPLACE" tells SAS to replace the dataset if there is already one named the same as specified by the "out" statement.

This is a basic use of Proc Import. It is a powerful tool with many uses and options. We will expand on this in future posts.