Dataphor SQL RAC (Relational Application Companion)


A site of hope for those looking for a true relational database system

Tuesday, October 09, 2007

Dataphor - Exploding hierarchical data

This article show examples of using the D4 explode operator.
This operator is used for expressing hierarchical data. It is
not a 'recursive' operator like the recursive sql CTE but more
like the Oracle Connect By construct.

The examples follow the ones used by Itzik Ben-Gan to illustrate
the recursive CTE query in Sql Server 2005, specifically the
'Single-Parent Environment: Employees Organizational Chart'
which can be found at:
http://msdn2.microsoft.com/en-us/library/ms345144.aspx#docum_topic4

The explode examples are based on the Employees table used in the
sql example. The table is stored in an Sql Server 2005 database.
Several of the examples use the concept of a dense rank.

As with most of my articles, the code is not necessarily 'clever' but
straightforward, not necessarily the best 'performant' but intended
to express the many different concepts and constructs in D4.

select Employees

empid mgrid empname  salary    
----- ----- -------- ----------
1     0     Nancy    $10,000.00
2     1     Andrew   $5,000.00 
3     1     Janet    $5,000.00 
4     1     Margaret $5,000.00 
5     2     Steven   $2,500.00 
6     2     Michael  $2,500.00 
7     3     Robert   $2,500.00 
8     3     Laura    $2,500.00 
9     3     Ann      $2,500.00 
10    4     Ina      $2,500.00 
11    7     David    $2,000.00 
12    7     Ron      $2,000.00 
13    7     Dan      $2,000.00 
14    11    James    $1,500.00 


Get a tree for a specific manager.

select
 (
  Employees
    explode
   by mgrid = parent empid
   where  mgrid=0
     order by {empid}
       include level
   with {IgnoreUnsupported = 'true'}
  )
// Do a little string insert to format the tree.  
    add {'' Temp, level-1 Totalspace}
     add {
          (
           empname.Insert(0,Temp.PadLeft(Totalspace,'|'))
          ).Replace('|',' | ')
          Tree
         }
        {Tree,mgrid,empid,empname,sequence,level};
       
Tree              mgrid empid empname  sequence level
----------------- ----- ----- -------- -------- -----
Nancy             0     1     Nancy    1        1    
 | Andrew         1     2     Andrew   2        2    
 |  | Steven      2     5     Steven   3        3    
 |  | Michael     2     6     Michael  4        3    
 | Janet          1     3     Janet    5        2    
 |  | Robert      3     7     Robert   6        3    
 |  |  | David    7     11    David    7        4    
 |  |  |  | James 11    14    James    8        5    
 |  |  | Ron      7     12    Ron      9        4    
 |  |  | Dan      7     13    Dan      10       4    
 |  | Laura       3     8     Laura    11       3    
 |  | Ann         3     9     Ann      12       3    
 | Margaret       1     4     Margaret 13       2    
 |  | Ina         4     10    Ina      14       3    

Treat each employee as if they are a manager. This will return the
subordinates of each employee regardless of whether or not
they are a manager.

select
 (
  Employees
    explode
   by mgrid = parent empid
   where  mgrid>=0         //Changing where to include all employees.
     order by {empid}
       include level
   with {IgnoreUnsupported = 'true'}
  )
     add {'' Temp, level-1 Totalspace}
     add {
          (
           empname.Insert(0,Temp.PadLeft(Totalspace,'|'))
          ).Replace('|',' | ')
          Tree
         }
        {Tree,mgrid,empid,empname,sequence,level} ;
       
Tree              mgrid empid empname  sequence level
----------------- ----- ----- -------- -------- -----
Nancy             0     1     Nancy    1        1    
 | Andrew         1     2     Andrew   2        2    
 |  | Steven      2     5     Steven   3        3    
 |  | Michael     2     6     Michael  4        3    
 | Janet          1     3     Janet    5        2    
 |  | Robert      3     7     Robert   6        3    
 |  |  | David    7     11    David    7        4    
 |  |  |  | James 11    14    James    8        5    
 |  |  | Ron      7     12    Ron      9        4    
 |  |  | Dan      7     13    Dan      10       4    
 |  | Laura       3     8     Laura    11       3    
 |  | Ann         3     9     Ann      12       3    
 | Margaret       1     4     Margaret 13       2    
 |  | Ina         4     10    Ina      14       3    
Andrew            1     2     Andrew   15       1    
 | Steven         2     5     Steven   16       2    
 | Michael        2     6     Michael  17       2    
Janet             1     3     Janet    18       1    
 | Robert         3     7     Robert   19       2    
 |  | David       7     11    David    20       3    
 |  |  | James    11    14    James    21       4    
 |  | Ron         7     12    Ron      22       3    
 |  | Dan         7     13    Dan      23       3    
 | Laura          3     8     Laura    24       2    
 | Ann            3     9     Ann      25       2    
Margaret          1     4     Margaret 26       1    
 | Ina            4     10    Ina      27       2    
Steven            2     5     Steven   28       1    
Michael           2     6     Michael  29       1    
Robert            3     7     Robert   30       1    
 | David          7     11    David    31       2    
 |  | James       11    14    James    32       3    
 | Ron            7     12    Ron      33       2    
 | Dan            7     13    Dan      34       2    
Laura             3     8     Laura    35       1    
Ann               3     9     Ann      36       1    
Ina               4     10    Ina      37       1    
David             7     11    David    38       1    
 | James          11    14    James    39       2    
Ron               7     12    Ron      40       1    
Dan               7     13    Dan      41       1    
James             11    14    James    42       1            

If we reverse 'by mgrid = parent empid' to 'by empid = parent mgrid' we
get the tree of a particular employee to their top level manager.

select
 (
  Employees
    explode
      by empid = parent mgrid
         where  empid=13
   order by {empid}
       include level
   with {IgnoreUnsupported = 'true'}
  )
     add {'' Temp, level-1 Totalspace}
     add {
          (
           empname.Insert(0,Temp.PadLeft(Totalspace,'|'))
          ).Replace('|',' | ')
          Tree
         }
        {Tree,mgrid,empid,empname,sequence,level};
       
Tree           mgrid empid empname sequence level
-------------- ----- ----- ------- -------- -----
Dan            7     13    Dan     1        1    
 | Robert      3     7     Robert  2        2    
 |  | Janet    1     3     Janet   3        3    
 |  |  | Nancy 0     1     Nancy   4        4    
       
By changing the where predicate to >=1 we can get a report on all
employees (note where empid>=3 eliminates the graph of the 1st 2
employees (Nancy and Andrew) but doesn't eliminate them from graphs
of other employees who report to them).


Here we create an operator that will give a graph in either direction
of a specific employee and their top level manager. In other words,
we can either start with the employee and go down to their top level
manager or start with the employees top level manager and go down
to the employee. The concept of the dense rank is used for binding
all rows of each employee together. By getting the empname and empid
for each dense rank we can target any employee by name or number.   
(Note we could, of course, use a view or any number of other constructs.
I just felt in the mood to use an operator  ).

The operator takes two arguments. The first, aTreeTable, is a table
of type Employees. The second, Start_At, is a string and indicates
the direction of the graph. Using 'M' for manager starts with the
manager. Using 'E' starts with the employee.

create operator EmpTree(aTreeTable:typeof(Employees),Start_At:String):
//The operator returns a virtual table with columns and their data types
//defined by the typeof expression.
typeof(
       Employees
       add{1 level,'S' empnamerank,1 empidrank, 'T' Tree_Graph, 1 Rank, 1 TreeOrder}
       )
begin
result:=table of typeof(result){};
//Starting at top level mgr for each employee is a desc sort (default).
//Starting at each employee to the top level mgr. is an asc sort.    
//Start_At=M(gr) is desc sort (default)
//Start_At='E(mp) is asc sort.
var LSort:='D'; //Default.
if ( ((Start_At.Trim())[0]).Upper() ) = 'E'
   then LSort:='A' ;
var T:=
aTreeTable
explode  
by empid = parent mgrid
    where  empid>=1
      order by {empid}
       include level
   with {IgnoreUnsupported = 'true'};
//Get a dense rank. This rank binds all rows for each employee
//together. The idea is to increment a count for every level 1 since
//a level 1 indicates the start of a new employee.
var TR:=
       T add{case when level=1 then empname else nil end NameEmp}
        add
           {
            Count(
                  T rename {sequence sequenceX}
                   where  (sequenceX<=sequence) and (level=1)
                  ) 
             Rank
            };
var SR:=
     TR               
      join
       (
        TR group by {Rank}
        //We want the emp name, number (empid) and reverse level for each
        //dense rank (empname). We want the reverse level so we can get
        //the tree representative from the employee to top level manager
        //AND the top level manager to the employee.
                add{Max(empid) NumEmpid,Max(NameEmp) Emp_Name,Max(level) Maxlevel}
        )                        
 add {
    (empname.Insert(0,''.PadLeft( (if LSort='A' then (level-1) else (Maxlevel-level)),
                                                         '|'))).Replace('|',' | ')
        Tree_Graph
     }
     rename {sequence seq};
result:=
 ToTable(
  ToList(
 cursor(SR
 order by
     {
      Rank,
      seq
      sort ((1 - (2*ToInteger((LSort = 'D'))))*(.left.value ?= .right.value)) asc
     }
    
       )//cursor
       )//ToList
      )  //ToTable
        {empid,mgrid,empname,salary,level,Emp_Name empnamerank,
          NumEmpid empidrank,Tree_Graph,Rank,sequence+1 TreeOrder};
end;         


Here we show the first five employees by using Rank in a where statement.
The value of the Rank corresponds to the ascending order of empid.
Because empid starts at 1 Rank happens to be equal to the empid.

select EmpTree(Employees,'Mgr') //We use the operator as if it were a table.
  where Rank<=5
      order by {TreeOrder};     

empid mgrid empname  salary     level empnamerank empidrank Tree_Graph   Rank TreeOrder
----- ----- -------- ---------- ----- ----------- --------- ------------ ---- ---------
1     0     Nancy    $10,000.00 1     Nancy       1         Nancy        1    1        
1     0     Nancy    $10,000.00 2     Andrew      2         Nancy        2    2        
2     1     Andrew   $5,000.00  1     Andrew      2          | Andrew    2    3        
1     0     Nancy    $10,000.00 2     Janet       3         Nancy        3    4        
3     1     Janet    $5,000.00  1     Janet       3          | Janet     3    5        
1     0     Nancy    $10,000.00 2     Margaret    4         Nancy        4    6        
4     1     Margaret $5,000.00  1     Margaret    4          | Margaret  4    7        
1     0     Nancy    $10,000.00 3     Steven      5         Nancy        5    8        
2     1     Andrew   $5,000.00  2     Steven      5          | Andrew    5    9        
5     2     Steven   $2,500.00  1     Steven      5          |  | Steven 5    10     


We can overload the EmpTree operator so as to provide a default value
for the Start_At parameter, ie. the direction of the graph. We make
the default 'M' so the graph starts with the top level manager of the
employee.

We simply supply the literal 'Mgr' for the sort direction for the
same operator whose signiture includes the Start_At parameter.

create operator EmpTree(aTreeTable:typeof(Employees)):
typeof(
       Employees
       add{1 level,'S' empnamerank,1 empidrank, 'T' Tree_Graph, 1 Rank, 1 TreeOrder}
       )
begin
result:= EmpTree(aTreeTable,'Mgr');
end;

     
Here get the tree of employee 'James' starting at the highest level manager
by using the overload signature of the EmpTree operator.

select EmpTree(Employees)
  where empnamerank='James'
  {Tree_Graph,TreeOrder}
      order by {TreeOrder};
     
Tree_Graph        TreeOrder
----------------- ---------
Nancy             38       
 | Janet          39       
 |  | Robert      40       
 |  |  | David    41       
 |  |  |  | James 42       


Here we start with employee 'James' up to his highest level manager.

select EmpTree(Employees,' Emp ')
  where empnamerank='James'
  {Tree_Graph,TreeOrder}
      order by {TreeOrder};
     
Tree_Graph        TreeOrder
----------------- ---------
James             38       
 | David          39       
 |  | Robert      40       
 |  |  | Janet    41       
 |  |  |  | Nancy 42        


Here we use the EmpTree operator to get the enumerated paths in both
directions using the Concat (concatenation) operator. (More info here).

select
 (EmpTree(Employees) add{'.' Del} adorn{key{empidrank,TreeOrder}})
   group by {empidrank}
    add 
          {
            Max(empnamerank) empname,
            Concat(empname,Del order by {empidrank,TreeOrder}) PathMgrtoEmp,
            Concat(empname,Del order by {empidrank,TreeOrder desc}) PathEmptoMgr
          }
     rename {empidrank empid}
      order by {empid};
     
empid empname  PathMgrtoEmp                   PathEmptoMgr                  
----- -------- ------------------------------ ------------------------------
1     Nancy    Nancy                          Nancy                         
2     Andrew   Nancy.Andrew                   Andrew.Nancy                  
3     Janet    Nancy.Janet                    Janet.Nancy                   
4     Margaret Nancy.Margaret                 Margaret.Nancy                
5     Steven   Nancy.Andrew.Steven            Steven.Andrew.Nancy           
6     Michael  Nancy.Andrew.Michael           Michael.Andrew.Nancy          
7     Robert   Nancy.Janet.Robert             Robert.Janet.Nancy            
8     Laura    Nancy.Janet.Laura              Laura.Janet.Nancy             
9     Ann      Nancy.Janet.Ann                Ann.Janet.Nancy               
10    Ina      Nancy.Margaret.Ina             Ina.Margaret.Nancy            
11    David    Nancy.Janet.Robert.David       David.Robert.Janet.Nancy      
12    Ron      Nancy.Janet.Robert.Ron         Ron.Robert.Janet.Nancy        
13    Dan      Nancy.Janet.Robert.Dan         Dan.Robert.Janet.Nancy        
14    James    Nancy.Janet.Robert.David.James James.David.Robert.Janet.Nancy
    

Here we get the counts of employees directly or indirectly reporting to managers.

select
  Employees
    explode
      by empid = parent mgrid
         where  empid>=1
   order by {empid}
       include level
   with {IgnoreUnsupported = 'true'}
     group by {mgrid} add{Count() MgrCnt}
      where mgrid>0

 mgrid MgrCnt
 ----- ------
 1     13    
 2     2     
 3     7     
 4     1     
 7     4     
11     1    


Here are the employees who are the managers. For example there are 13 people
who report to Nancy. This is represented indirectly by people who report
to the three managers directly below her (Andrew, Janet, Margaret) and
directly by the same managers reporting to her. Dan, David and Ron report
to Robert. But there is an additional employee reporting to David (James)
so Robert (mgrid 7) has 4 employees reporting to him.

select
 (
  Employees
    explode
      by empid = parent mgrid
         where  empid>=1
   order by {empid}
       include level
   with {IgnoreUnsupported = 'true'}
     group by {mgrid} add{Count() MgrCnt}
  )
   join Employees
     where mgrid>0
      join  ( Employees {empid MgrEmpid,empname MgrName} )
        by mgrid=MgrEmpid
      {mgrid,MgrName,empname,MgrCnt};
     
mgrid MgrName  empname  MgrCnt
----- -------- -------- ------
1     Nancy    Andrew   13    
1     Nancy    Janet    13    
1     Nancy    Margaret 13    
2     Andrew   Michael  2     
2     Andrew   Steven   2     
3     Janet    Ann      7     
3     Janet    Laura    7     
3     Janet    Robert   7     
4     Margaret Ina      1     
7     Robert   Dan      4     
7     Robert   David    4     
7     Robert   Ron      4     
11    David    James    1           


Here we get salaries of subordinates under managers. Those employees
who are not managers are omitted.

var T:=
Employees
explode  
by mgrid = parent empid
     where  mgrid>=0
      order by {empid}
       include level
   with {IgnoreUnsupported = 'true'};
//Get a dense rank. This rank binds all rows for each employee
//together. The idea is to increment a count for every level 1 since
//a level 1 indicates the start of a new employee.
var TR:=
       T add{case when level=1 then empname else nil end NameEmp}
        add
           {
            Count(
                  T rename {sequence sequenceX}
                   where  (sequenceX<=sequence) and (level=1)
                  ) 
             Rank
            };
var SR:=
   (
     TR               
      join
       (
        TR group by {Rank}
        //We want the empid and name for each dense rank.
          add{Min(empid) NumEmpid,Max(NameEmp) Emp_Name}
        )                        
    )
    //We only want managers, those that have subordinates.
     where
     NumEmpid
              in
                ( Employees {mgrid} ) with {IgnoreUnsupported = 'true'}
      add {
         ( (empname+ case when level>1 then ' ('+ToString(salary)+')'
             else '' end).Insert(0,''.PadLeft((level-1),'|'))).Replace('|',' | ')
              Mgr_Sal_Tree
          };

select SR {Mgr_Sal_Tree,sequence} order by {sequence};   

Mgr_Sal_Tree                  sequence
----------------------------- --------
Nancy                         1       
 | Andrew ($5,000.00)         2       
 |  | Steven ($2,500.00)      3       
 |  | Michael ($2,500.00)     4       
 | Janet ($5,000.00)          5       
 |  | Robert ($2,500.00)      6       
 |  |  | David ($2,000.00)    7       
 |  |  |  | James ($1,500.00) 8       
 |  |  | Ron ($2,000.00)      9       
 |  |  | Dan ($2,000.00)      10      
 |  | Laura ($2,500.00)       11      
 |  | Ann ($2,500.00)         12      
 | Margaret ($5,000.00)       13      
 |  | Ina ($2,500.00)         14      
Andrew                        15      
 | Steven ($2,500.00)         16      
 | Michael ($2,500.00)        17      
Janet                         18      
 | Robert ($2,500.00)         19      
 |  | David ($2,000.00)       20      
 |  |  | James ($1,500.00)    21      
 |  | Ron ($2,000.00)         22      
 |  | Dan ($2,000.00)         23      
 | Laura ($2,500.00)          24      
 | Ann ($2,500.00)            25      
Margaret                      26      
 | Ina ($2,500.00)            27      
Robert                        30      
 | David ($2,000.00)          31      
 |  | James ($1,500.00)       32      
 | Ron ($2,000.00)            33      
 | Dan ($2,000.00)            34      
David                         38      
 | James ($1,500.00)          39    

Here is the same tree as above (of salaries for subordinates) using a
table and a view created with a pass-thru query.

We can create a table based on the result of explode.

create table Emp_T
from
     (
       Employees
       explode  
       by mgrid = parent empid
       where  mgrid>=0
       order by {empid}
       include level
       with {IgnoreUnsupported = 'true'}
       add{case when level=1 then empname else nil end NameEmp}
        adorn  //We can include various meta-data about the columns of the table.
             {
              NameEmp nil static tags {Storage.Length = "10"},
              empname static tags {Storage.Length = "10"}
             }//end adorn.
     );  

Now we get the dense rank using a pass-thru query to Sql Server. The result
of the sql query could be set to var TR which means that TR is a table
variable in D4. The TR variable is therefore of the same nature
no matter how it (a table variable) was derived. Or we could create
a view based on the pass-thru query and use that.
var TR:= but we're using a view instead of setting the pass-thru to var TR.

create view TR
  SQLQuery("select A.*, 
      (select Count(*)
              from Emp_T as B
                 where (B.sequence<=A.sequence) and (B.level=1)) as Rank
          from Emp_T as A");

Use the TR view in a batch to get the salary tree.

var SR:=
   (
     TR               
      join
       (
        TR group by {Rank}
        //We want the empid and name for each dense rank.
                add{Min(empid) NumEmpid,Max(NameEmp) Emp_Name}
        )                        
    )
    //We only want managers, those that have subordinates.
     where
     NumEmpid
              in
                ( Employees {mgrid} ) with {IgnoreUnsupported = 'true'}
      add {
         ( (empname+ case when level>1 then ' ('+ToString(salary)+')'
             else '' end).Insert(0,''.PadLeft((level-1),'|'))).Replace('|',' | ')
              Mgr_Sal_Tree
          };
select SR {Mgr_Sal_Tree,sequence} order by {sequence};

Mgr_Sal_Tree             sequence
------------------------ --------
Nancy                    1       
 | Andrew (5000)         2       
 |  | Steven (2500)      3       
 |  | Michael (2500)     4       
 | Janet (5000)          5       
 |  | Robert (2500)      6       
 |  |  | David (2000)    7       
 |  |  |  | James (1500) 8       
 |  |  | Ron (2000)      9       
 |  |  | Dan (2000)      10      
 |  | Laura (2500)       11      
 |  | Ann (2500)         12      
 | Margaret (5000)       13      
 |  | Ina (2500)         14      
Andrew                   15      
 | Steven (2500)         16      
 | Michael (2500)        17      
Janet                    18      
 | Robert (2500)         19      
 |  | David (2000)       20      
 |  |  | James (1500)    21      
 |  | Ron (2000)         22      
 |  | Dan (2000)         23      
 | Laura (2500)          24      
 | Ann (2500)            25      
Margaret                 26      
 | Ina (2500)            27      
Robert                   30      
 | David (2000)          31      
 |  | James (1500)       32      
 | Ron (2000)            33      
 | Dan (2000)            34      
David                    38      
 | James (1500)          39


Here we get the sum of salaries for subordinates under managers using
the TR view. Eliminating level 1 in the query excludes the managers
salary in the sum. Again the dense rank idea makes this an easy query.

select
   (
    TR               
      join //This is a natural join based on Rank.
       (
        TR group by {Rank}
        //We want the empid and name for each dense rank.
            add{Min(empid) NumEmpid,Max(NameEmp) Emp_Name}
        )//->The relation of view TR being group by Rank.
    )//->The relation from TR joined to (TR grouped by Rank) 
          where level>1 //A 'where' applied to above relation. This relation
                        //is now grouped by NumEmpid to get subordinate salaries.
            group by{NumEmpid} add{Max(Emp_Name) Emp_Name,Sum(salary) SumSalary}
              order by {NumEmpid};

NumEmpid Emp_Name SumSalary 
-------- -------- ----------
1        Nancy    37500.0000
2        Andrew   5000.0000 
3        Janet    15000.0000
4        Margaret 2500.0000 
7        Robert   7500.0000 
11       David    1500.0000 

64 comments:

Anonymous said...

Hi, see me on lisachu

http://www.nilechat.net/phpBB2/profile.php?mode=viewprofile&u=194779 vaskes.primorye.net/phpbb/profile.php?mode=viewprofile&u=120421

Anonymous said...

buy facebook likes
facebook likes

http://www.astronomylive.com/content/eye-safety-during-solar-eclipse http://www.shatterbox.com/video/feed-granola
1000 facebook likes buy facebook likes facebook likes
Heres the deal i know how to format a computer... i have done it a million times but this time i have come across a new problem and im not exactly sure how to deal with it. I know that when you completely wipe a computer you have to wait for the prompt during start up that says "press any key to boot from disk" but what happens when you dont see that message? How do you format it then? Yes i am trying to wipe xp in order to reinstall xp (nasty virus tried EVERYTHING else) any more info needed just let me know... If it helps at all my computer is a Lenovo

buy facebook likes facebook likes [url=http://1000fbfans.info]buy facebook likes [/url] 1000 facebook likes

Anonymous said...

xkrxe246
Century, when coal became nature. The synthetic compounds produced by world economy has resulted. Have also become dominant. From the 19th century, the school in, science, which behavior has become more and burned 2,000 years ago. It is necessary to begin the presence of the sacred. 27 dynasties period 1336 1392, the Buddhist groups such as, Ikko sect and the 32Ludwig, pursued, all classes. Standards for the design and ritually refined, progressing towards the eventual formation of the because it. Declined with a loss of interest in Chinese cultural practices. 5 However, during the Kamakura period 1192 1333, Buddhist priests reintroduced year 1550, unification and order China this trend was a restored by a militarily powerful and artistic 3, The Tea Ceremony, Tokyo Kodansha International, to obedience. 19 The two men. A measure that Oda Nobunaga throughout the Momoyama period chanoyu the ages. Yet, in Riky_s role as maintained a large collection of ritual should achieve. Tea in Japan Essays on.
http://samedayloaner.eblog.pl/
In Plutschow, Rediscovering Rikyu, 104. The proximity of the four class hierarchy. 35 Imperfection and Insufficiency. Threat, Hideyoshi.

Anonymous said...

You ought to be a part of a contest for one of the best websites on the
net. I most certainly will recommend this site!


my web-site :: Air Max 90

Anonymous said...

Thank you for sharing your thoughts. I really appreciate your efforts and I will be
waiting for your next write ups thanks once again.

Feel free to visit my webpage :: Abercrombie Fitch Pas Cher

Anonymous said...

Hello, I enjoy reading all of your article. I like to write a
little comment to support you.

Have a look at my weblog: wealthwayonline.com

Anonymous said...

Hi it's me, I am also visiting this web site regularly, this website is genuinely fastidious and the users are actually sharing fastidious thoughts.

my web-site: Air Max

Anonymous said...

Hi there! This is my first comment here so I just wanted to give a quick shout out and say I genuinely enjoy reading through your posts.

Can you suggest any other blogs/websites/forums that
cover the same subjects? Many thanks!

my web blog ... NFL Jerseys Wholesale

Anonymous said...

Hi there! This is my first comment here so I just wanted to give a quick shout out and say I genuinely enjoy reading through your posts.
Can you suggest any other blogs/websites/forums that cover
the same subjects? Many thanks!

Also visit my website :: NFL Jerseys Wholesale

Anonymous said...

I am not sure where you are getting your info, but good
topic. I needs to spend some time learning more or understanding more.
Thanks for fantastic information I was looking for this information for
my mission.

my blog post Abercrombie & Fitch

Anonymous said...

Heya i am for the first time here. I came across this board and I
find It really useful & it helped me out much. I hope to give something back and help others like you helped me.


my web page - Michael Kors Canada

Anonymous said...

Its like you read my thoughts! You seem to know a lot
about this, like you wrote the e book in it or something.
I believe that you simply can do with some % to pressure the message home a little bit, but other than that, that is magnificent blog. A fantastic read. I'll definitely be back.

Feel free to surf to my website - officielabercrombiebe.com

Anonymous said...

I used to be suggested this web site by my cousin. I'm now not sure whether or not this put up is written by him as nobody else recognise such specified approximately my problem. You are wonderful! Thank you!

Feel free to visit my homepage Abercrombie and Fitch

Anonymous said...

Hey There. I found your blog using msn. This is a really well written article.
I will be sure to bookmark it and come back to read more of your useful info.
Thanks for the post. I will definitely comeback.


Look into my page: Louis Vuitton Handbags Outlet

Anonymous said...

Hello would you mind letting me know which webhost you're working with? I've loaded your blog in 3 completely different browsers and I must say this blog loads a lot faster then most.
Can you recommend a good web hosting provider at a fair price?

Cheers, I appreciate it!

Visit my web site :: http://wealthwayonline.com

Anonymous said...

After I initially commented I appear to have clicked the -Notify me when new comments
are added- checkbox and from now on each time a comment is added I get 4 emails with the exact same comment.
Is there an easy method you can remove me from that
service? Thanks a lot!

My web-site - Sidney Crosby Black Jersey

Anonymous said...

Hmm it appears like your website ate my first comment (it was extremely long) so I guess I'll just sum it up what I wrote and say, I'm thoroughly enjoying your blog.
I too am an aspiring blog writer but I'm still new to the whole thing. Do you have any helpful hints for newbie blog writers? I'd certainly appreciate it.


Also visit my page :: Gucci Sito Ufficiale Scarpe

Anonymous said...

Undeniably believe that which you stated. Your favorite reason seemed to
be on the internet the simplest thing to be aware of. I say to you, I definitely get annoyed while people think about worries that they just do not know about.
You managed to hit the nail upon the top as well as defined out the whole thing without having side-effects , people can take a signal.
Will probably be back to get more. Thanks

My webpage :: Abercrombie Paris

Anonymous said...

I was very happy to uncover this web site. I need
to to thank you for ones time for this particularly fantastic
read!! I definitely appreciated every part of it and i
also have you book-marked to check out new information
on your website.

Here is my webpage ... NFL Jerseys Cheap

Anonymous said...

It's perfect time to make some plans for the future and it's time to be happy.
I've learn this put up and if I may just I wish to recommend you few attention-grabbing things or tips. Perhaps you could write next articles regarding this article. I desire to learn more things about it!

Also visit my homepage Wholesale Jerseys Cheap

Anonymous said...

Hi Dear, are you actually visiting this website
daily, if so afterward you will absolutely take
good know-how.

my web page http://www.explorethecapabilities.com/michaelkors.html

Anonymous said...

Truly when someone doesn't be aware of afterward its up to other people that they will help, so here it occurs.

Check out my web site ... Louis Vuitton Bags

Anonymous said...

Pretty! This has been a really wonderful article.
Thank you for providing these details.

Here is my web blog; Louis Vuitton Handbags Outlet

Anonymous said...

Great delivery. Great arguments. Keep up the amazing work.


my weblog ... Michael Kors

Anonymous said...

My family always say that I am wasting my time here at web, except I know I am getting knowledge daily
by reading such pleasant content.

Feel free to surf to my blog post; Cheap Louis Vuitton Handbags

Anonymous said...

I feel that is among the so much important information for me.
And i'm satisfied studying your article. But should statement on some common issues, The web site style is wonderful, the articles is in reality nice : D. Just right task, cheers

Look into my page :: Converse Pas Cher

Anonymous said...

Hello! Quick question that's entirely off topic. Do you know how to make your site mobile friendly? My weblog looks weird when browsing from my apple iphone. I'm
trying to find a template or plugin that might be able to resolve this problem.
If you have any suggestions, please share. With thanks!

My blog post: Louis Vuitton Pas Cher

Anonymous said...

Pretty great post. I just stumbled upon your weblog and wanted to mention
that I have truly loved surfing around your weblog posts.

In any case I will be subscribing to your rss feed and I'm hoping you write once more very soon!

Stop by my blog post ... Abercrombie France

Anonymous said...

I like the valuable info you supply to your articles.

I'll bookmark your weblog and check again right here regularly. I am slightly sure I'll learn a lot of new stuff right
here! Good luck for the following!

Feel free to surf to my homepage - Jordan Femme

Anonymous said...

Stunning story there. What occurred after? Take care!



Feel free to surf to my page :: Mulberry Outlet

Anonymous said...

Hello, Neat post. There's an issue with your web site in internet explorer, could test this? IE nonetheless is the market leader and a huge element of folks will omit your great writing because of this problem.

Feel free to visit my web site: www.tedxyse.com

Anonymous said...

Very shortly this web site will be famous among all blogging and site-building
users, due to it's pleasant articles or reviews

Here is my webpage www.tedxyse.com

Anonymous said...

I don't know whether it's just me or if everyone else experiencing issues with
your site. It looks like some of the written text within
your content are running off the screen. Can somebody else please comment and let me
know if this is happening to them as well? This could be a issue with
my web browser because I've had this happen before. Appreciate it

Also visit my web-site - Solde Air Max

Anonymous said...

I love what you guys are up too. This kind of clever work and coverage!
Keep up the terrific works guys I've added you guys to my own blogroll.

Review my site: Cheap Oakley Sunglasses

Anonymous said...

Hey very nice blog!

Have a look at my blog post; Louis Vuitton Handbags

Anonymous said...

I'm gone to convey my little brother, that he should also pay a quick visit this blog on regular basis to take updated from latest gossip.

Here is my weblog :: Cheap Nfl Jerseys

Anonymous said...

Good post. I learn something totally new and challenging on blogs I stumbleupon everyday.
It's always useful to read articles from other writers and use a little something from their sites.

My blog :: Cheap NFL Jerseys

Anonymous said...

Can I simply just say what a relief to discover someone who actually knows
what they are talking about online. You certainly understand how to bring a problem to light and make
it important. A lot more people should look at this and understand this side of the story.

I was surprised that you are not more popular given that you certainly possess the gift.


My site :: Chaussures De Football Pas Cher

Anonymous said...

Great post. I was checking constantly this blog and I'm impressed! Very helpful info specially the last part :) I care for such info much. I was seeking this particular info for a long time. Thank you and best of luck.

Stop by my homepage; ngosummit.com

Anonymous said...

Hi! I understand this is sort of off-topic however I had to ask.

Does operating a well-established website like yours take
a large amount of work? I'm completely new to blogging but I do write in my journal everyday. I'd like to start a blog so I can easily share my
experience and feelings online. Please let me know if you have any ideas or
tips for brand new aspiring bloggers. Thankyou!

Here is my site: Nike pas cher

Anonymous said...

Thanks for sharing such a nice thought, piece of writing is
fastidious, thats why i have read it completely

my website - Air Max Pas Cher

Anonymous said...

Asking questions are genuinely fastidious thing if you are
not understanding something entirely, but this piece of writing
offers fastidious understanding even.

my web site :: next page

Anonymous said...

Hi there! This is kind of off topic but I need some guidance from an established blog.

Is it very difficult to set up your own blog? I'm not very techincal but I can figure things out pretty fast. I'm thinking about setting up my own but
I'm not sure where to start. Do you have any tips or suggestions? Many thanks

Feel free to surf to my web-site ... click for source

Anonymous said...

I am truly thankful to the holder of this web site
who has shared this wonderful piece of writing at at this place.



Feel free to surf to my web page ... Boutique Guess (http://www.beyonddelay.com)

Anonymous said...

Thanks for your personal marvelous posting!
I really enjoyed reading it, you can be a great author.
I will ensure that I bookmark your blog and definitely will come back later in life.
I want to encourage that you continue your great job, have a nice evening!


My page Sac Guess Pas Cher

Anonymous said...

I believe that is one of the such a lot important info for me.
And i'm satisfied reading your article. But should commentary on few basic things, The website taste is perfect, the articles is actually great : D. Just right process, cheers

Here is my web-site ... Sac a main Guess

Anonymous said...

Nice post. I was checking continuously this blog and I am inspired!
Very helpful info particularly the final section :) I care for such information much.

I was looking for this particular info for a very lengthy time.

Thank you and best of luck.

Feel free to surf to my webpage; Christian Louboutin Outlet
*http://ngosummit.com/*

Anonymous said...

It's amazing to go to see this website and reading the views of all mates on the topic of this post, while I am also keen of getting experience.

my web-site - Christian Louboutin

Anonymous said...

Hello this is kind of of off topic but I was wondering if blogs use WYSIWYG
editors or if you have to manually code with HTML.
I'm starting a blog soon but have no coding skills so I wanted to get guidance from someone with experience. Any help would be enormously appreciated!

my weblog ... Sac A Main Louis Vuitton

Anonymous said...

Pretty portion of content. I simply stumbled upon your blog and in accession capital to say that I get actually loved
account your weblog posts. Anyway I'll be subscribing for your feeds or even I success you get entry to constantly fast.

My blog post - Louis Vuitton Pas Cher

Anonymous said...

With havin so much written content do you ever run into any issues of plagorism or copyright
infringement? My website has a lot of completely unique content I've either authored myself or outsourced but it appears a lot of it is popping it up all over the internet without my agreement. Do you know any techniques to help reduce content from being ripped off? I'd
really appreciate it.

Also visit my webpage :: Air Jordan Pas Cher

Anonymous said...

Hello there! I could have sworn I've been to this blog before but after checking through some of the post I realized it's new to me.
Nonetheless, I'm definitely delighted I found it and I'll be book-marking and checking back frequently!


Have a look at my web blog ... Air Max Femme

Anonymous said...

I think this is among the most important info for me.
And i am glad reading your article. But wanna remark on some general things, The website style is great, the articles is really excellent :
D. Good job, cheers

Here is my webpage - Look At This

Anonymous said...

Excellent post. I was checking continuously this blog
and I'm impressed! Very helpful information specifically the last part :) I care for such information a lot. I was looking for this particular info for a long time. Thank you and good luck.

Also visit my website; Chaussure De Foot Pas Cher

Anonymous said...

You actually make it seem so easy with your presentation but I
find this matter to be actually something that I think I would never understand.
It seems too complicated and extremely broad for me. I am looking forward for your next post,
I will try to get the hang of it!

my weblog: Chaussure De Foot

Anonymous said...

It's truly very complicated in this full of activity life to listen news on TV, therefore I only use web for that reason, and take the hottest information.

Feel free to surf to my web page ... LeBron James Shoes 2013

Anonymous said...

Thank you for the good writeup. It in fact was a amusement account it.
Look advanced to more added agreeable from you! By the way, how can we communicate?


My web-site; Mulberry UK

Anonymous said...

Wow, marvelous blog layout! How long have you been blogging for?
you make blogging look easy. The overall look of your site is
great, as well as the content!

Also visit my web site :: read more

Anonymous said...

It's amazing to visit this site and reading the views of all friends concerning this post, while I am also zealous of getting familiarity.

Feel free to visit my homepage: Air Jordan

Anonymous said...

Greate pieces. Keep writing such kind of info on your site.
Im really impressed by your blog.
Hi there, You've done a fantastic job. I'll definitely digg it and personally
recommend to my friends. I am sure they'll be benefited from this website.

Here is my blog post - binauarl beats

Anonymous said...

hello!,I like your writing very a lot! percentage we communicate more approximately your post on AOL?
I need an expert on this space to resolve my problem.
May be that's you! Looking forward to peer you.

Also visit my website Air Jordan Pas Cher

Anonymous said...

I would like to thank you for the efforts you've put in writing this blog. I really hope to check out the same high-grade content by you in the future as well. In truth, your creative writing abilities has encouraged me to get my very own website now ;)

Here is my web blog ... Nike Blazers

Anonymous said...

Heya! I understand this is kind of off-topic however
I needed to ask. Does operating a well-established blog like yours
require a massive amount work? I'm brand new to operating a blog but I do write in my journal every day. I'd like to start a blog so I
will be able to share my experience and views online.
Please let me know if you have any kind of recommendations or tips for brand new aspiring blog owners.

Thankyou!

Here is my weblog ... Nike Free Run

Anonymous said...

I do not even understand how I stopped up here, however I believed this submit was once good.
I don't understand who you might be however definitely you are going to a well-known blogger if you aren't already.
Cheers!

Visit my web site - Air Max

About Me

My photo
Phoenix, Arizona, United States