<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule">
<channel>
    <title>Sune Trudslev's WebLog - SQL</title>
    <link>http://www.tanis.dk/blog/</link>
    <description>Advanced concepts -- Easy explainations</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.4 - http://www.s9y.org/</generator>
    <pubDate>Fri, 30 Sep 2005 18:20:14 GMT</pubDate>

    <image>
        <url>http://www.tanis.dk/blog/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Sune Trudslev's WebLog - SQL - Advanced concepts -- Easy explainations</title>
        <link>http://www.tanis.dk/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>SQL: SELECT by priority</title>
    <link>http://www.tanis.dk/blog/archives/20-SQL-SELECT-by-priority.html</link>
            <category>SQL</category>
    
    <comments>http://www.tanis.dk/blog/archives/20-SQL-SELECT-by-priority.html#comments</comments>
    <wfw:comment>http://www.tanis.dk/blog/wfwcomment.php?cid=20</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.tanis.dk/blog/rss.php?version=2.0&amp;type=comments&amp;cid=20</wfw:commentRss>
    

    <author>nospam@example.com (Sune Trudslev)</author>
    <content:encoded>
    &lt;p&gt;I have been working on a project at work where it should be possible to set up what suppliers are available to our customers and their users. We also wanted to be able to be able to provide the customers with a standard setup (sort of a template) based on what type of product they are using. &lt;/p&gt;&lt;p&gt;Here is the solution I came up with.&lt;/p&gt;&lt;p /&gt;&lt;hr /&gt;&lt;p /&gt;&lt;p&gt;First the tables we already have available:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Customer&lt;/strong&gt;&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Column Name&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Value&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;CustomerId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Int (PK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CustomerName&lt;/td&gt;&lt;td&gt;Varchar(30)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Office&lt;/strong&gt;&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Column Name&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Value&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;OfficeId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Int (PK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CustomerId&lt;/td&gt;&lt;td&gt;Int (FK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SupplierTemplateId&lt;/td&gt;&lt;td&gt;Int (FK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OfficeName&lt;/td&gt;&lt;td&gt;Varchar(30)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Supplier&lt;/strong&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Column Name&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Value&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;SupplierId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Int (PK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SupplierName&lt;/td&gt;&lt;td&gt;Varchar(30)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;So then we will need to add a table to hold the templates:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SupplierTemplate&lt;/strong&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Column Name&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Value&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;SupplierTemplateId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Int (PK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SupplierTemplateName&lt;/td&gt;&lt;td&gt;Varchar(30)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;Last but not least we will need a table to hold the actual supplier selection:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SupplierSetting&lt;/strong&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Column Name&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Value&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;SupplierSettingId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Int (PK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SupplierId&lt;/td&gt;&lt;td&gt;Int (FK)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SupplierTemplateId&lt;/td&gt;&lt;td&gt;Int (FK) NULL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CustomerId&lt;/td&gt;&lt;td&gt;Int (FK) NULL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OfficeId&lt;/td&gt;&lt;td&gt;Int (FK) NULL&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Enabled&lt;/td&gt;&lt;td&gt;Bit&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Priority&lt;/td&gt;&lt;td&gt;Int&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;A setting can either belong to a template, a customer, a registration number or none (which makes it a default setting).&lt;/p&gt;&lt;p&gt;The priority is assigned as follows:&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Condition&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Priority&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;No owner&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Owned by a template&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Owned by a customer&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Owned by a registration&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;So now we can fill in some data:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Customer&lt;/strong&gt;&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;CustomerId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;CustomerName&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Test Customer&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SupplierTemplate&lt;/strong&gt;&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;SupplierTemplateId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;SupplierTemplateName&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Template 1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Office&lt;/strong&gt;&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;OfficeId&lt;/td&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;CustomerId&lt;/td&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;SupplierTemplateId&lt;/td&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;OfficeName&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 25%&quot;&gt;Test Office&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Supplier&lt;/strong&gt;&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;SupplierId&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;SupplierName&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Test Supplier 1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;2&lt;/td&gt;&lt;td style=&quot;WIDTH: 50%&quot;&gt;Test Supplier 2&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;Now all that is left is set up the suppliers:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SupplierSetting&lt;/strong&gt;&lt;br /&gt;&lt;table style=&quot;WIDTH: 100%&quot; cellspacing=&quot;1&quot; cellpadding=&quot;1&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;SupplierSettingId&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;SupplierId&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;SupplierTemplateId&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;CustomerId&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;OfficeId&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;Enabled&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;Priority&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;true&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;2&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;2&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;false&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;3&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;2&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;true&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;4&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;1&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;NULL&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;false&lt;/td&gt;&lt;td style=&quot;WIDTH: 14%&quot;&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;br /&gt;Here is a textual representation of the above data:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;On a global (default) level &#039;Test Supplier 1&#039; is turned on and &#039;Test Supplier 2&#039; is turned off.&lt;/li&gt;&lt;li&gt;On &#039;Test Customer&#039; level &#039;Test Supplier 2&#039; is turned on&#039;&lt;/li&gt;&lt;li&gt;On &#039;Test Office&#039; level &#039;Test Supplier 1&#039; is turned off.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So how do we get this data out so we only have one row per supplier with the correct status? Well, the answer is a SELECT statement with a sub-SELECT to find the highest priority for the current supplier. Enjoy!&lt;/p&gt;&lt;p&gt;Here it is:&lt;/p&gt;&lt;pre&gt;&lt;span lang=&quot;EN-GB&quot; style=&quot;FONT-SIZE: 12pt; FONT-FAMILY: &quot;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span lang=&quot;EN-GB&quot; style=&quot;FONT-SIZE: 12pt; FONT-FAMILY: &quot;&gt;DECLARE @OfficeId INT&lt;br /&gt;SELECT @OfficeId = 1&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span lang=&quot;EN-GB&quot; style=&quot;FONT-SIZE: 12pt; FONT-FAMILY: &quot;&gt;DECLARE @CustomerId INT&lt;br /&gt;DECLARE @SupplierTemplateId INT&lt;br /&gt;SELECT&lt;br /&gt;  &lt;/span&gt;&lt;span lang=&quot;EN-GB&quot; style=&quot;FONT-SIZE: 12pt; FONT-FAMILY: &quot;&gt;@CustomerId = CustomerId,&lt;br /&gt;  @SupplierTemplateId = SupplierTemplateId &lt;br /&gt;FROM &lt;br /&gt;  Office &lt;br /&gt;WHERE &lt;br /&gt;  OfficeId = @OfficeId&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span lang=&quot;EN-GB&quot; style=&quot;FONT-SIZE: 12pt; FONT-FAMILY: &quot;&gt;SELECT &lt;br /&gt;  * &lt;br /&gt;FROM &lt;br /&gt;  SupplierSetting s1 &lt;br /&gt;WHERE &lt;br /&gt;  (CustomerId  = @CustomerId OR CustomerId IS NULL) AND&lt;br /&gt;  (SupplierTemplateId = @SupplierTemplateId OR SupplierTemplateId IS NULL) AND&lt;br /&gt;  (OfficeId = @OfficeId OR OfficeId IS NULL) AND&lt;br /&gt;  Priority = (&lt;br /&gt;    SELECT &lt;br /&gt;      MAX(Priority) &lt;br /&gt;    FROM &lt;br /&gt;      SupplierSetting s2 &lt;br /&gt;    WHERE &lt;br /&gt;      s1.SupplierId = s2.SupplierId AND&lt;br /&gt;      (CustomerId  = @CustomerId OR CustomerId IS NULL) AND&lt;br /&gt;      (SupplierTemplateId = @SupplierTemplateId OR SupplierTemplateId IS NULL) AND&lt;br /&gt;      (OfficeId = @OfficeId OR OfficeId IS NULL)&lt;br /&gt;  )&lt;/span&gt;&lt;/pre&gt;&lt;p /&gt; 
    </content:encoded>

    <pubDate>Fri, 30 Sep 2005 18:57:00 +0200</pubDate>
    <guid isPermaLink="false">http://www.tanis.dk/blog/archives/20-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/</creativeCommons:license>
</item>

</channel>
</rss>