<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Saki's Blog &#187; sql</title>
	<atom:link href="http://blog.extjs.eu/tag/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.extjs.eu</link>
	<description>For good of all productive developers</description>
	<lastBuildDate>Mon, 16 Aug 2010 23:12:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Displaying 1:n Data in Grid</title>
		<link>http://blog.extjs.eu/know-how/displaying-1n-data-in-grid/</link>
		<comments>http://blog.extjs.eu/know-how/displaying-1n-data-in-grid/#comments</comments>
		<pubDate>Sun, 11 May 2008 17:13:13 +0000</pubDate>
		<dc:creator>Saki</dc:creator>
				<category><![CDATA[Know-how]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://blog.extjs.eu/?p=68</guid>
		<description><![CDATA[<br/>The Problem
Imagine that you have a one-to-many relationship in your database, for example, you have table person in which you keep personal data (first, middle, last names, etc.) and you have table phone where you keep phone numbers (phone type, phone number).
It is quite common to have person:phones, company:phones, order:items, invoice:items, etc relationships, isn&#8217;t it?
Now, [...]]]></description>
			<content:encoded><![CDATA[<br/><h1>The Problem</h1>
<p>Imagine that you have a one-to-many relationship in your database, for example, you have table <b><code>person</code></b> in which you keep personal data (first, middle, last names, etc.) and you have table <b><code>phone</code></b> where you keep phone numbers (phone type, phone number).</p>
<p>It is quite common to have person:phones, company:phones, order:items, invoice:items, etc relationships, isn&#8217;t it?</p>
<p>Now, it is quite easy to create a grid that displays list of persons but what about their phones? They are in the different table. Yes, we could create two stores: one for persons grid and another, hidden, for phones, load them from server and somehow filter phones depending on persons.</p>
<p>Nevertheless, I was looking for a simpler solution as I wanted one client server round trip and I wanted to display &#8220;many&#8221; data in QuickTip. And I found one&#8230;</p>
<h1>Solution &#8211; Server Side</h1>
<p><a href="http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat" target="_blank">MySql</a>, that I use as my main database backend, has function <b><code>group_concat</code></b> since version 4.1 and <a href="http://www.sqlite.org/lang_aggfunc.html" target="_blank">SQLite</a> has it since version 3.5.</p>
<p>The idea is to join tables <b><code>person</code></b> and <b><code>phone</code></b> server side and return &#8220;many&#8221; data in one extra field as string separated by arbitrary separators. The SQL statement would be as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> 
    persFirstName<span style="color: #66cc66;">,</span> persMidName<span style="color: #66cc66;">,</span> persLastName<span style="color: #66cc66;">,</span>
    group_concat<span style="color: #66cc66;">&#40;</span>concat_ws<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'~'</span><span style="color: #66cc66;">,</span> phoneType<span style="color: #66cc66;">,</span> phoneNumber<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'|'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> phones
<span style="color: #993333; font-weight: bold;">FROM</span> person
    <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> phone <span style="color: #993333; font-weight: bold;">ON</span> person<span style="color: #66cc66;">.</span>persID<span style="color: #66cc66;">=</span>phone<span style="color: #66cc66;">.</span>persIDs
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> person<span style="color: #66cc66;">.</span>persID</pre></div></div>

<p><b><code>phones</code></b> part of the output of the above sql would look like</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Home~<span style="color: #000000;">123456</span><span style="color: #000000; font-weight: bold;">|</span>Work~<span style="color: #000000;">87654</span><span style="color: #000000; font-weight: bold;">|</span>Mobile~<span style="color: #000000;">654321</span></pre></div></div>

<h1>Solution &#8211; Client Side</h1>
<p>We cannot display received phones directly in <b><code>person</code></b> grid (well we could but users would hate us) but we need some processing. I decided to display phones in QuickTips so I needed custom renderer for <b><code>persLastName</code></b>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
 * Last Name rederer including tooltip with phones
 * @param {Mixed} val Value to render
 * @param {Object} cell
 * @param {Ext.data.Record} record
 */</span>
<span style="color: #339933;">,</span>renderLastName<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>val<span style="color: #339933;">,</span> cell<span style="color: #339933;">,</span> record<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// get data</span>
    <span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> record.<span style="color: #660066;">data</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// convert phones to array (only once)</span>
    data.<span style="color: #660066;">phones</span> <span style="color: #339933;">=</span> 
        Ext.<span style="color: #660066;">isArray</span><span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">phones</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> data.<span style="color: #660066;">phones</span> <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">getPhones</span><span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">phones</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// create tooltip</span>
    <span style="color: #003366; font-weight: bold;">var</span> qtip <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">qtipTpl</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">phones</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// return markup</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #3366CC;">'&lt;div qtip=&quot;'</span> <span style="color: #339933;">+</span> qtip <span style="color: #339933;">+</span><span style="color: #3366CC;">'&quot;&gt;'</span> <span style="color: #339933;">+</span> val <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&lt;/div&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #006600; font-style: italic;">// eo function renderLastName</span></pre></div></div>

<p>and <b><code>getPhones</code></b> function:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
 * Converts string phones to array of objects
 * @param {String} phones
 * @return {Array} Array of phone objects
 */</span>
<span style="color: #339933;">,</span>getPhones<span style="color: #339933;">:</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>phones<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// empty array if nothing to do</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>phones<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// init return value</span>
    <span style="color: #003366; font-weight: bold;">var</span> retval <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// split string to phones</span>
    <span style="color: #003366; font-weight: bold;">var</span> aps <span style="color: #339933;">=</span> phones.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'|'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// iterate through phones to extract phoneType and phoneNumber</span>
    Ext.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>aps<span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>phone<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003366; font-weight: bold;">var</span> a <span style="color: #339933;">=</span> phone.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'~'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        retval.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>phoneType<span style="color: #339933;">:</span>a<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> phoneNumber<span style="color: #339933;">:</span>a<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">return</span> retval<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #006600; font-style: italic;">// eo function getPhones</span></pre></div></div>

<p>A bit of XTemplate work for QuickTips and we&#8217;re done.</p>
<h1>Conclusion</h1>
<p>This is not full fledged one-to-many data handling with editing, adding and deleting items at &#8220;many&#8221; side, it is just simple display of data from &#8220;many&#8221; table, anyway, it can come handy sometimes.</p>
<p>You can see the working example here: <a href="http://examples.extjs.eu/?ex=one2many" target="_blank">http://examples.extjs.eu</a></p>
<p>The &#8220;many&#8221; display target does not need to be QuickTip, it can be row expander as well.<br />
<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><div class="paypal-donations"><input type="hidden" name="cmd" value="_donations" /><input type="hidden" name="business" value="js02@aariadne.com" /><input type="hidden" name="item_number" value="Blog Donation" /><input type="hidden" name="currency_code" value="EUR" /><input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-butcc-donate.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /><img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /></div></form></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.extjs.eu/know-how/displaying-1n-data-in-grid/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
