Humpty Dumpty sat on a wall, Humpty Dumpty took a big fall, All the kings horses and all the kings men, Couldn't put Humpty together again. It seems people are always running into the same problem with concatenating strings in sql. But we can put Humpty together very easily in Dataphor. Lets concatenate the strings that we created in the banana split post. First we'll create a table and insert the split strings. This is the familiar sql operation of insert/select. create table exampleconcat { ID : Integer, index : Integer, strpart : String, key {ID,index} } insert ( examplesplit times numbers where Split(STRING,{ ':',',','/' } ).Count()>DIGIT add {Split(STRING,{ ':',',','/' } ).Count() cnt, Split(STRING,{ ':',',','/' } )[DIGIT].Trim() strpart} {strpart,DIGIT+1 index,ID} ) into exampleconcat But wait a minute will ya. Notice there's no 'select'. That's because in sql 'select' is part of all expressions. In Dataphor it's only a statement. Not only is its meaning logical, it;s intuitive. In Dataphor you you can order 'select' a la carte, not so in sql:) This is a BIG deal as you shall see as we get more involved with queries. An even BIGGER deal is that Dataphor inserts data independent of ordinal position. It's only concerned with matching the names of the columns. The columns to be inserted specified by: {strpart,DIGIT+1 index,ID} could be scrambled any way you want. The order has no relationalship to the sequence of columns declared in table 'exampleconcat'.In all the places that sql requires taking into account the order of columns, you needn't concern yourself about it in Dataphor. select exampleconcat ID index strpart -- ----- ------- 1 1 AA 1 2 BB 1 3 CC 1 4 DD 1 5 EE 1 6 FF 1 7 GG 2 1 KK 2 2 JJ 2 3 II 2 4 HH 2 5 AA 2 6 BB 3 1 LL 3 2 MM 3 3 NN 3 4 PP 4 1 QQQ 4 2 RRRR To concatenate the strings for each ID is childs play:) The concat operator is like an aggregate function,ie. count,min,max etc. You group by ID and add the concat operator. It takes 3 arguments,the string column, a delimiter and an order by column for how you want the result ordered. select exampleconcat add {',' Delimiter} group by {ID} add { Concat(strpart,Delimiter order by {index}) concatstr } ID concatstr -- -------------------- 1 AA,BB,CC,DD,EE,FF,GG 2 KK,JJ,II,HH,AA,BB 3 LL,MM,NN,PP 4 QQQ,RRRR Are you impressed?:) Before I let you go a few words about add. Yeah, it's a BIG deal:) Consider this. Lets create a table of 1 row and a single column X with a value of 5. select ToTable({5},'X') X - 5 Now add another column to the table, Y. select ToTable({5},'X') add {6 Y} X Y - - 5 6 Now add the expression X*Y. select ToTable({5},'X') add {6 Y} add {X*Y XY} X Y XY - - -- 5 6 30 Now add an expression involving XY and Y. select ToTable({5},'X') add {6 Y} add {X*Y XY} add {XY-Y Z} X Y XY Z - - -- -- 5 6 30 24 See a pattern here? Remember high school algebra?:) Well this is algebra with tables! You know the problem that sql has with using expressions (aliases) within the same select? Gone. The often repeated sql question: 'why can't I use an alias defined in 'select' in the 'where' statement?' select ToTable({5},'X') add {6 Y} add {X*Y XY} add {XY-Y Z} where Z>20 Gone. Fini. Case closed:) Compare this to t-sql. select X,Y,XY,XY-Y Z from (select X,Y,X*Y XY from (select 5 as X,6 as Y) t1 ) t2 You have to select each expression before you can use it in another expression. Give me a break:) What is the mathematical concept that describes this sql behavior? Mess, from the latin idea of messi?:) Did someone ask about subqueries? You guessed it, you add subqueries just like any other expression. And another post. And yes I could talk about the sql need of table aliases (t1,t2) but I feel magnanimous now so I won't beat a dead horse:) Hang with me for just a few more seconds I want to show you something really interesting. Lets suppose in our example we want ID's with a string count of greater than 4. First we'll add the Count() aggregate to the concat aggregate. We'll call the count 'cnt'. select exampleconcat add {',' Delimiter} group by {ID} add { Concat(strpart,Delimiter order by {index}) concatstr,Count() cnt } ID concatstr cnt -- -------------------- --- 1 AA,BB,CC,DD,EE,FF,GG 7 2 KK,JJ,II,HH,AA,BB 6 3 LL,MM,NN,PP 4 4 QQQ,RRRR 2 To get the ID's with a count greater than 4 you would use 'having' in sql right? As in 'having count()>4'. This gets to the fact that in sql there are 2 different statements that perform the same conceptual thing ie. a restriction. And the one you use depends on whether your grouping ('having') or operating on non grouped data ('where'). The usual reason given when newbies ask about this is 'thats the way it works in sql'. Good thing the designers of this sql mess didn't go into medicine:) Now in Dataphor after the 2nd add we have a table. How do you restrict the rows of a table? Yep with where. One where fits all(situations):) There is no logical reason for 'with this use that, with that use this'. So it's as simple as this: select exampleconcat add {',' Delimiter} group by {ID} add { Concat(strpart,Delimiter order by {index}) concatstr,Count() cnt } where cnt>4 order by {cnt desc} ID concatstr cnt -- -------------------- --- 1 AA,BB,CC,DD,EE,FF,GG 7 2 KK,JJ,II,HH,AA,BB 6 Since we're we using an algebra for tables we can add parenthesis around the statements that make up the table we're applying where to: select ( exampleconcat add {',' Delimiter} group by {ID} add { Concat(strpart,Delimiter order by {index}) concatstr,Count() cnt } ) where cnt>4 order by {cnt desc} Ok, thanks for sticking around. There's much more to come!
Dataphor SQL RAC (Relational Application Companion)
A site of hope for those looking for a true relational database system
- a one-one requirement constraint with dataphor (1)
- anatomy of sql server part I - what is a stored procedure (1)
- anatomy of sql server part II - the unit test as part of the database (1)
- anatomy of sql server part III - what does deferred name resolution really mean (1)
- censoring sql posts (1)
- creating an opposite constraint in dataphor (1)
- dataphor (2)
- Dataphor (7)
- dataphor # 13 a table as a parameter (1)
- dataphor - download and start working with it (1)
- dataphor - fixed sized word segments (1)
- dataphor # 10 sql mythology (1)
- dataphor # 11 string differences (1)
- dataphor # 12 trimming a string (1)
- dataphor # 14 sql the meaning of Update..From (1)
- dataphor # 15 views with substance (1)
- dataphor # 16 inclusive vs exclusive solutions (1)
- dataphor # 17 a visual look at ranking queries (1)
- dataphor # 18 data scrubbing using lists (1)
- dataphor # 19 create intervals over strings (1)
- dataphor # 20 browsing an sql window (1)
- dataphor # 21 an example of relational division (1)
- dataphor # 22 reusable procedures (1)
- dataphor # 23 repley to Michel (1)
- dataphor # 24 basics of the table type (1)
- dataphor # 25 extending the dense rank function (1)
- dataphor # 26 query a hierarchy with explode (1)
- dataphor # 27 combine strings with Split and Concat (1)
- dataphor # 28 constants and variables or sql and D4 (1)
- dataphor # 29 another example of relational division (1)
- dataphor #1 introduction (1)
- dataphor #2 splitting strings (1)
- dataphor #3 string concatenation (1)
- dataphor #4 comment (1)
- dataphor #5 comment (1)
- dataphor #6 formal definition (1)
- dataphor #7 sql: table this (1)
- dataphor #8 list to table (1)
- dataphor #9 table constraints (1)
- dataphor creating lists in a query (1)
- extracting numbers from a string with dataphor (1)
- jeff modens dynamic crosstabs for sql server (1)
- linq to sql the what and why (1)
- linq to sql as a window of opportunity to sql users (1)
- linq to sql should be important to sql users (1)
- linq to sql vs. older 4GL attempts (1)
- listing missing table item (1)
- Multiple cascade paths to the same table (1)
- RAC (4)
- RAC #1 comment (1)
- RAC #2 example (1)
- RAC #3 finding the Nth number in a string (1)
- RAC #4 Sql Server 2005 ranking functions vs. Rac ranking (1)
- sorting a delimited string by its numerical string parts (1)
- sql an example of extreme implicit conversions (1)
- sql can't handle complicated cascading updates (1)
- sql CTE should be a variable not a value (1)
- sql dense rank for identifying consecutive runs (1)
- sql is there really a table variable (1)
- sql ranking functions explained by relational types (1)
- sql server triggers are best set based (1)
- sql the idea of using substring to simulate lists (1)
- sql the undefined trigger in Sql Server (1)
- sql vs relational on tables (1)
- sql what the sql CTE covers up (1)
- types and procedures (1)
Saturday, August 12, 2006
Dataphor - Solving the Humpty Dumpty Problem
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment