<?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>SQL &#8211; Customer Experience Management</title>
	<atom:link href="https://mietwood.com/tag/sql/feed" rel="self" type="application/rss+xml" />
	<link>https://mietwood.com</link>
	<description>Customer Experience Can Be Managed</description>
	<lastBuildDate>Tue, 14 Oct 2025 07:38:53 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://mietwood.com/wp-content/uploads/2022/09/cropped-Fav7-32x32.png</url>
	<title>SQL &#8211; Customer Experience Management</title>
	<link>https://mietwood.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Optimizing SQL query for billions of records table &#8211; a powerful tips</title>
		<link>https://mietwood.com/optimizing-sql-query</link>
					<comments>https://mietwood.com/optimizing-sql-query#comments</comments>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Tue, 14 Oct 2025 06:03:40 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3360</guid>

					<description><![CDATA[<p>For a table with billions of records, optimizing SQL query is crucial. The main problem with the query is that it applies functions (YEAR, MONTH, DATEFROMPARTS) to the ORDERDATE column within the GROUP BY clause. This forces the database to perform a calculation for every single row before it can group them, preventing the efficient...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/optimizing-sql-query">Optimizing SQL query for billions of records table &#8211; a powerful tips</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>For a table with billions of records, optimizing SQL query is crucial. The main problem with the query is that it applies functions (<code>YEAR</code>, <code>MONTH</code>, <code>DATEFROMPARTS</code>) to the <code>ORDERDATE</code> column within the <code>GROUP BY</code> clause. This forces the database to perform a calculation for every single row before it can group them, preventing the efficient use of an index on <code>ORDERDATE</code>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>-- The query
SELECT 
   ss.SOLDTONBR,
   datefromparts(year(ORDERDATE),month(ORDERDATE),1) order_date
from ss
group by 
   ss.SOLDTONBR,
   datefromparts(year(ORDERDATE),month(ORDERDATE),1)
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">The</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">query</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #D8DEE9">ss</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">SOLDTONBR</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #88C0D0">datefromparts</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">year</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ORDERDATE</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span><span style="color: #88C0D0">month</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ORDERDATE</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">order_date</span></span>
<span class="line"><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ss</span></span>
<span class="line"><span style="color: #D8DEE9">group</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">by</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #D8DEE9">ss</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">SOLDTONBR</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #88C0D0">datefromparts</span><span style="color: #D8DEE9FF">(</span><span style="color: #88C0D0">year</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ORDERDATE</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span><span style="color: #88C0D0">month</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">ORDERDATE</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p>How to optimize this query?</p>



<h3 class="wp-block-heading">The Problem of optimizing SQL query: Preventing Index Usage</h3>



<p>The query is not <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-theme-palette-2-color"><strong>SARGable</strong> (Searchable Argument-able</mark>). This means the database engine can&#8217;t use an index to find the data it needs directly. Instead, it must perform a <strong>full table scan</strong>, reading all billion rows from the disk, calculating the first day of the month for each one, and then grouping the results. This is incredibly slow and resource-intensive.</p>



<h3 class="wp-block-heading">Optimization Strategies</h3>



<h4 class="wp-block-heading">Create a Composite Index &#8211; The Biggest Win</h4>



<p>Regardless of how you rewrite the query, the most important step is to have the right index. Since you are grouping by <code>SOLDTONBR</code> and then by a derivative of <code>ORDERDATE</code>, the ideal index would cover both columns.</p>



<pre class="wp-block-code"><code>CREATE INDEX IX_ss_SoldToNbr_OrderDate ON ss (SOLDTONBR, ORDERDATE);</code></pre>



<p>This index allows the database to quickly access the data pre-sorted by <code>SOLDTONBR</code> and <code>ORDERDATE</code>, making the grouping operation vastly more efficient. Optimizing SQL query.</p>



<p>Optimisation tips you can also find here: <a href="https://mietwood.com/sql-tips">15 Essential SQL Tips You Can&#8217;t Live Without</a></p>



<p>Column store indices for MS SQL Server you can find <a href="https://learn.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-overview?view=sql-server-ver17" target="_blank" rel="noopener">here</a></p>



<h4 class="wp-block-heading">Use More Efficient Date Functions</h4>



<p>Instead of combining <code>YEAR</code> and <code>MONTH</code>, use a single, more efficient function to truncate the date to the beginning of the month. The best function depends on your specific database system. These functions are often better optimized internally. Optimizing SQL query.</p>



<ul class="wp-block-list">
<li><strong>SQL Server:</strong>SQL<code>-- Best for modern SQL Server SELECT ss.SOLDTONBR, DATETRUNC(month, ORDERDATE) AS order_date FROM ss GROUP BY ss.SOLDTONBR, DATETRUNC(month, ORDERDATE);</code></li>



<li><strong>PostgreSQL / Redshift:</strong>SQL<code>SELECT ss.SOLDTONBR, DATE_TRUNC('month', ORDERDATE) AS order_date FROM ss GROUP BY ss.SOLDTONBR, DATE_TRUNC('month', ORDERDATE);</code></li>



<li><strong>MySQL:</strong>SQL<code>SELECT ss.SOLDTONBR, DATE_FORMAT(ORDERDATE, '%Y-%m-01') AS order_date FROM ss GROUP BY ss.SOLDTONBR, order_date; -- MySQL allows using alias in GROUP BY</code></li>



<li><strong>Oracle:</strong>SQL<code>SELECT ss.SOLDTONBR, TRUNC(ORDERDATE, 'MM') AS order_date FROM ss GROUP BY ss.SOLDTONBR, TRUNC(ORDERDATE, 'MM');</code></li>
</ul>



<p>While better, these still apply a function to the column, which can limit performance. The index from step 1 is still what makes the biggest difference.</p>



<h4 class="wp-block-heading">3. The Gold Standard: A Date Dimension Table</h4>



<p>For very large tables (like yours), the best practice is to use a <strong>date dimension table</strong>. This is a static lookup table containing one row for every day over a long period (e.g., 100 years). It has pre-calculated columns for everything you might need: first day of the month, week of the year, quarter, etc.</p>



<p>Here you can see how to create a Date Dimension Table using recursive CTE: <a href="https://mietwood.com/recursive-cte-in-sql-server">How Works Recursive CTE in SQL Server?</a></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>SET DATEFIRST  1,
    DATEFORMAT ymd,
    LANGUAGE   US_ENGLISH;

-- Define date range
DECLARE @StartDate  date = '20220101';
DECLARE @CutoffDate date = DATEADD(DAY, -1, DATEADD(YEAR, 5, @StartDate));

-- Recursive CTE to generate date dimension
WITH seq(n) AS 
(
    SELECT 0
    UNION ALL
    SELECT n + 1
    FROM seq
    WHERE n &lt; DATEDIFF(DAY, @StartDate, @CutoffDate)
),
DateDimension AS
(
    SELECT 
        DATEADD(DAY, n, @StartDate) AS Date,
        DATENAME(WEEKDAY, DATEADD(DAY, n, @StartDate)) AS DayName,
        DATEPART(WEEKDAY, DATEADD(DAY, n, @StartDate)) AS DayOfWeek,
        DATEPART(DAY, DATEADD(DAY, n, @StartDate)) AS Day,
        DATEPART(MONTH, DATEADD(DAY, n, @StartDate)) AS Month,
        DATENAME(MONTH, DATEADD(DAY, n, @StartDate)) AS MonthName,
        DATEPART(YEAR, DATEADD(DAY, n, @StartDate)) AS Year,
        DATEPART(QUARTER, DATEADD(DAY, n, @StartDate)) AS Quarter,
        DATEPART(WEEK, DATEADD(DAY, n, @StartDate)) AS WeekOfYear,

        CASE 
            WHEN DATEPART(WEEKDAY, DATEADD(DAY, n, @StartDate)) IN (1, 7) THEN 1
            ELSE 0
        END AS IsWeekend
    FROM seq
      
)
SELECT
    dd.*,
    k.WeekOfYear_fdt
FROM
    DateDimension dd
LEFT JOIN
    (
        SELECT
            Year,
            WeekOfYear,
            MIN(Date) as WeekOfYear_fdt
        FROM DateDimension
        GROUP BY Year, WeekOfYear
    ) AS k ON k.Year = dd.Year AND k.WeekOfYear = dd.WeekOfYear
ORDER BY
    Date
OPTION (MAXRECURSION 0);</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">SET</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DATEFIRST</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">DATEFORMAT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ymd</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">LANGUAGE</span><span style="color: #D8DEE9FF">   </span><span style="color: #D8DEE9">US_ENGLISH</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">range</span></span>
<span class="line"><span style="color: #D8DEE9">DECLARE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D08770">@StartDate</span><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">20220101</span><span style="color: #ECEFF4">&#39;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">DECLARE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D08770">@CutoffDate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">YEAR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CTE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">to</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">generate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dimension</span></span>
<span class="line"><span style="color: #D8DEE9">WITH</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">seq</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">UNION</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ALL</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seq</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">WHERE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEDIFF</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">CutoffDate</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9">DateDimension</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span></span>
<span class="line"><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Date</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATENAME</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEKDAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DayName</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEKDAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DayOfWeek</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Day</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MONTH</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Month</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATENAME</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MONTH</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MonthName</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">YEAR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Year</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">QUARTER</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Quarter</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEK</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">WeekOfYear</span><span style="color: #ECEFF4">,</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">CASE</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEKDAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #88C0D0">IN</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">7</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">ELSE</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">END</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">IsWeekend</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seq</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span></span>
<span class="line"><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">dd</span><span style="color: #ECEFF4">.</span><span style="color: #81A1C1">*</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">k</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">WeekOfYear_fdt</span></span>
<span class="line"><span style="color: #D8DEE9">FROM</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">DateDimension</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dd</span></span>
<span class="line"><span style="color: #D8DEE9">LEFT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">JOIN</span></span>
<span class="line"><span style="color: #D8DEE9FF">    (</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">SELECT</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">Year</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">WeekOfYear</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #88C0D0">MIN</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> WeekOfYear_fdt</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DateDimension</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">GROUP</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">BY</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Year</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">WeekOfYear</span></span>
<span class="line"><span style="color: #D8DEE9FF">    ) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ON</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Year</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dd</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Year</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AND</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">WeekOfYear</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dd</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">WeekOfYear</span></span>
<span class="line"><span style="color: #D8DEE9">ORDER</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">BY</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">Date</span></span>
<span class="line"><span style="color: #88C0D0">OPTION</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">MAXRECURSION</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="747" height="324" src="https://mietwood.com/wp-content/uploads/2025/10/image.jpg" alt="Optimizing SQL query" class="wp-image-3366" srcset="https://mietwood.com/wp-content/uploads/2025/10/image.jpg 747w, https://mietwood.com/wp-content/uploads/2025/10/image-300x130.jpg 300w" sizes="(max-width: 747px) 100vw, 747px" /><figcaption class="wp-element-caption">Optimizing SQL query</figcaption></figure>
</div>


<p><strong>Example <code>DimDate</code> Table:</strong></p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td>DateKey</td><td>FullDate</td><td>FirstOfMonth</td><td>Year</td><td>MonthName</td><td>WeekOfYear</td></tr></thead><tbody><tr><td>20251012</td><td>2025-10-12</td><td>2025-10-01</td><td>2025</td><td>October</td><td>41</td></tr><tr><td>20251013</td><td>2025-10-13</td><td>2025-10-01</td><td>2025</td><td>October</td><td>42</td></tr><tr><td>20251014</td><td>2025-10-14</td><td>2025-10-01</td><td>2025</td><td>October</td><td>42</td></tr><tr><td>&#8230;</td><td>&#8230;</td><td>&#8230;</td><td>&#8230;</td><td>&#8230;</td><td>&#8230;</td></tr></tbody></table></figure>



<p></p>



<p><strong>How to Use It:</strong></p>



<p>You join your main table to <code>DimDate</code>. The expensive <code>GROUP BY</code> calculation is replaced with a fast join and a group on a pre-calculated column.</p>



<p>SQL. Optimizing SQL query.</p>



<pre class="wp-block-code"><code>SELECT
    ss.SOLDTONBR,
    d.FirstOfMonth AS order_date
FROM
    ss
INNER JOIN
    DimDate d ON ss.ORDERDATE = d.FullDate -- Assumes ORDERDATE has no time component
GROUP BY
    ss.SOLDTONBR,
    d.FirstOfMonth;
</code></pre>



<p><strong>Why this is the most efficient:</strong></p>



<ul class="wp-block-list">
<li><strong>No on-the-fly calculations:</strong> The grouping is done on a column that is already calculated (<code>d.FirstOfMonth</code>).</li>



<li><strong>Index-friendly:</strong> The join <code>ss.ORDERDATE = d.FullDate</code> can use indexes on both columns for maximum speed.</li>



<li><strong>Flexibility:</strong> It makes grouping by any other time period (week, quarter) trivial and just as fast.</li>
</ul>



<h3 class="wp-block-heading">Grouping by Week of the Year</h3>



<p>To group by week, you can apply the same principles.</p>



<ol start="1" class="wp-block-list">
<li>Function-based (Less Efficient):Use a function like DATETRUNC(&#8216;week&#8217;, ORDERDATE) or DATEPART(week, ORDERDATE).SQL<code>-- Example for PostgreSQL / SQL Server SELECT ss.SOLDTONBR, DATETRUNC(week, ORDERDATE) as order_week FROM ss GROUP BY ss.SOLDTONBR, DATETRUNC(week, ORDERDATE);</code></li>



<li>Date Dimension Table (Most Efficient):This is the ideal way. Just change the column in your GROUP BY clause.SQL<code>SELECT ss.SOLDTONBR, d.WeekOfYear, -- Or a column representing the first day of the week d.Year FROM ss INNER JOIN DimDate d ON ss.ORDERDATE = d.FullDate GROUP BY ss.SOLDTONBR, d.WeekOfYear, d.Year;</code></li>
</ol>



<h3 class="wp-block-heading">Summary of Recommendations</h3>



<p>For a table with billions of records, follow these steps for maximum performance (Optimizing SQL query.):</p>



<ol start="1" class="wp-block-list">
<li><strong>Immediately create a composite index:</strong> <code>CREATE INDEX IX_ss_SoldToNbr_OrderDate ON ss (SOLDTONBR, ORDERDATE);</code></li>



<li><strong>For the ultimate solution, create and populate a Date Dimension table.</strong> Join to this table to perform your aggregations. This is the most scalable and flexible method.</li>



<li>If you cannot create a dimension table, <strong>replace your <code>DATEFROMPARTS(YEAR(...), MONTH(...))</code> logic</strong> with a more efficient, platform-specific function like <code>DATETRUNC()</code>. Optimizing SQL query.</li>
</ol>
<p>The post <a rel="nofollow" href="https://mietwood.com/optimizing-sql-query">Optimizing SQL query for billions of records table &#8211; a powerful tips</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mietwood.com/optimizing-sql-query/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>15 Essential SQL Tips You Can&#8217;t Live Without</title>
		<link>https://mietwood.com/sql-tips</link>
					<comments>https://mietwood.com/sql-tips#comments</comments>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Sat, 11 Oct 2025 15:54:17 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Business Analytics]]></category>
		<category><![CDATA[data science]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3353</guid>

					<description><![CDATA[<p>Whether you&#8217;re optimizing performance or simplifying your queries, these SQL tips from mietwood.com will help you write cleaner, faster, and more efficient code. SQL is the backbone of data-driven decision-making, and mastering it can dramatically improve how you interact with databases. Whether you&#8217;re a seasoned developer or just starting out, writing efficient, readable, and scalable...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/sql-tips">15 Essential SQL Tips You Can&#8217;t Live Without</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Whether you&#8217;re optimizing performance or simplifying your queries, these SQL tips from <a href="https://mietwood.com/10-tips-how-to-make-sql-lighter" target="_blank" rel="noreferrer noopener">mietwood.com</a> will help you write cleaner, faster, and more efficient code.</p>



<p>SQL is the backbone of data-driven decision-making, and mastering it can dramatically improve how you interact with databases. Whether you&#8217;re a seasoned developer or just starting out, writing efficient, readable, and scalable SQL queries is a skill that pays off daily. In this post, I’ve compiled ten essential tips that will help you write smarter SQL—tips that I’ve learned, refined, and shared over time. These aren’t just theoretical best practices; they’re practical techniques that can make your queries faster, your code cleaner, and your debugging easier.</p>



<p>You can try Microsoft SQL Server from here: <a href="https://www.microsoft.com/pl-pl/sql-server/sql-server-downloads" target="_blank" rel="noopener">https://www.microsoft.com/pl-pl/sql-server/sql-server-downloads</a>. And developer edition is <a href="https://go.microsoft.com/fwlink/p/?linkid=2215158&amp;clcid=0x415&amp;culture=pl-pl&amp;country=pl" target="_blank" rel="noopener">here</a> </p>



<p>From avoiding <code>SELECT *</code> to choosing the right join types, each tip is designed to help you think critically about how your queries perform and how they scale. You’ll also learn how to use indexes effectively, filter data early, and make smart choices between <code>EXISTS</code> and <code>IN</code>. Each section includes a short summary and a link to a full post where you can dive deeper into the topic. Whether you&#8217;re optimizing a legacy system or building something new, these tips will help you get the most out of SQL—and avoid common pitfalls that slow down your work.</p>



<h3 class="wp-block-heading"><strong>Select Only What You Need</strong>, SQL Tips no 1</h3>



<p>Avoid <code>SELECT *</code> and specify only the columns you need. This reduces data transfer, memory usage, and improves query speed. For example, instead of pulling all employee data, just select <code>employee_id</code>, <code>first_name</code>, and <code>last_name</code>.  <a href="https://mietwood.com/10-tips-how-to-make-sql-lighter" target="_blank" rel="noreferrer noopener">Read more</a></p>



<h3 class="wp-block-heading" id="1optimizejoinconditionsforperformance"><strong>Optimize Join Conditions for Performance</strong></h3>



<p>Avoid non-SARGable joins that prevent index usage. Instead of applying functions to columns in join conditions, restructure the logic to preserve index efficiency. This dramatically improves query speed. <a href="https://mietwood.com/query-optimization-with-join-condition">Read the full guide</a></p>



<h3 class="wp-block-heading" id="2usethepivotoperatorforbetterreporting"><strong>Use the PIVOT Operator for Better Reporting</strong></h3>



<p>Transform row-based data into columnar format using <code>PIVOT</code>. This is ideal for cross-tab reports and trend analysis, especially when comparing metrics across time or categories. <a href="https://mietwood.com/the-pivot-operator-in-sql">Explore the PIVOT tutorial</a></p>



<h3 class="wp-block-heading" id="3masterrecursivectesforhierarchicaldata"><strong>Master Recursive CTEs for Hierarchical Data</strong></h3>



<p>Recursive Common Table Expressions (CTEs) allow you to elegantly query hierarchical or tree-structured data. They’re powerful for tasks like organizational charts or category trees. <a href="https://mietwood.com/blog">Learn about recursive CTEs</a></p>



<h3 class="wp-block-heading" id="4setthefirstdayoftheweekwithdatefirst"><strong>Set the First Day of the Week with DATEFIRST</strong></h3>



<p>Use <code>SET DATEFIRST</code> to control how SQL Server interprets weekday numbers. This is crucial for accurate time-based reporting and week-based aggregations. <a href="https://mietwood.com/category/sql">See how to use DATEFIRST</a></p>



<h3 class="wp-block-heading" id="5updatemultipletableswithconditions"><strong>Update Multiple Tables with Conditions</strong></h3>



<p>Learn how to structure multi-table updates using joins and conditional logic. This technique is essential for synchronizing data across related tables. <a href="https://mietwood.com/category/sql">Read the multi-table update example</a></p>



<h3 class="wp-block-heading" id="7filterearlywithwhereclauses"><strong>Filter Early with WHERE Clauses</strong></h3>



<p>Apply filters as early as possible to reduce the number of rows processed in joins and aggregations. <a href="https://mietwood.com/10-tips-how-to-make-sql-lighter">Optimize your filtering</a></p>



<h3 class="wp-block-heading" id="8useunionallinsteadofunion"><strong>Use UNION ALL Instead of UNION</strong></h3>



<p><code>UNION ALL</code> is faster than <code>UNION</code> because it skips duplicate elimination. Use it when duplicates aren’t a concern. <a href="https://mietwood.com/10-tips-how-to-make-sql-lighter">Performance tip explained</a></p>



<h3 class="wp-block-heading" id="9avoidfunctionsonindexedcolumns"><strong>Avoid Functions on Indexed Columns</strong></h3>



<p>Using functions like <code>LOWER()</code> or <code>DATEADD()</code> on indexed columns disables index usage. Rewrite conditions to preserve index paths. <a href="https://mietwood.com/query-optimization-with-join-condition">Join optimization example</a></p>



<h3 class="wp-block-heading" id="10exploresqlforbusinessanalytics"><strong>Explore SQL for Business Analytics</strong></h3>



<p>Advanced SQL techniques like statistical analysis, predictive modeling, and time series forecasting are essential for business analysts. Learn how to combine SQL with Python for deeper insights. <a href="https://mietwood.com/advanced-programming-in-sql-and-python">Check out the full course</a></p>



<h2 class="wp-block-heading"><strong>5 additional SQL tips</strong></h2>



<h3 class="wp-block-heading"><strong>Use CTEs for Readability and Reuse</strong></h3>



<p>Common Table Expressions (CTEs) make complex queries easier to read and maintain. They allow you to define temporary result sets that can be referenced multiple times. SQL Tips</p>



<pre class="wp-block-code"><code>WITH recentorders AS (
  SELECT customerid, orderdate
  FROM orders
  WHERE orderdate > CURRENTDATE - INTERVAL '30 days'
)
SELECT customerid, COUNT(*) AS ordercount
FROM recentorders
GROUP BY customer_id;</code></pre>



<h3 class="wp-block-heading" id="12avoidfunctionsonindexedcolumns"><strong>Avoid Functions on Indexed Columns</strong></h3>



<p>Using functions on indexed columns disables index usage, slowing down queries. Instead, transform the value before comparison. SQL Tips</p>



<pre class="wp-block-code"><code>-- Avoid
SELECT FROM users WHERE LOWER(email) = 'test@example.com';
-- Better
SELECT FROM users WHERE email = 'test@example.com';</code></pre>



<h3 class="wp-block-heading" id="13usecaseforconditionallogic"><strong>Use CASE for Conditional Logic</strong></h3>



<p><code>CASE</code> lets you embed conditional logic directly in your queries, useful for categorizing or transforming data.</p>



<pre class="wp-block-code"><code>SELECT name,
  CASE
    WHEN score >= 90 THEN 'Excellent'
    WHEN score >= 75 THEN 'Good'
    ELSE 'Needs Improvement'
  END AS performance
FROM students;</code></pre>



<h3 class="wp-block-heading" id="14optimizeaggregationswithgroupby"><strong>Optimize Aggregations with GROUP BY</strong></h3>



<p>When aggregating data, ensure you&#8217;re grouping only necessary columns to avoid performance hits and incorrect results.</p>



<pre class="wp-block-code"><code>SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;</code></pre>



<h3 class="wp-block-heading" id="15useparameterizedqueriestopreventsqlinjection"><strong>Use Parameterized Queries to Prevent SQL Injection</strong></h3>



<p>Always use parameterized queries in application code to protect against SQL injection.</p>



<pre class="wp-block-code"><code>-- Example in Python with psycopg2
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))</code></pre>



<h2 class="wp-block-heading">Remember &#8211; tips summary</h2>



<h3 class="wp-block-heading"><strong>Use Joins Efficiently</strong></h3>



<p>Choose the right join type—<code>INNER JOIN</code> for matched rows, and avoid <code>CROSS JOIN</code> unless necessary. Efficient joins reduce unnecessary data processing and improve clarity.</p>



<h3 class="wp-block-heading"><strong>Filter Data Early</strong></h3>



<p>Apply filters as soon as possible in your query using <code>WHERE</code> clauses. This minimizes the number of rows processed in joins and aggregations, leading to faster execution. SQL Tips no 3</p>



<h3 class="wp-block-heading"><strong>Use Indexes Wisely</strong></h3>



<p>Indexes speed up data retrieval, especially in <code>WHERE</code>, <code>JOIN</code>, and <code>ORDER BY</code> clauses. But don’t over-index—too many can slow down <code>INSERT</code>, <code>UPDATE</code>, and <code>DELETE</code> operations.</p>



<h3 class="wp-block-heading"><strong>Avoid Subqueries in WHERE Clauses</strong></h3>



<p>Correlated subqueries can be slow. Replace them with joins when possible to improve performance and readability. SQL Tips no 4</p>



<h3 class="wp-block-heading"><strong>Use UNION ALL Instead of UNION</strong></h3>



<p><code>UNION</code> removes duplicates, which is costly. If duplicates aren’t a concern, use <code>UNION ALL</code> for faster results.</p>



<h3 class="wp-block-heading"><strong>Limit Your Results</strong></h3>



<p>Use <code>LIMIT</code> or <code>TOP</code> to restrict the number of rows returned. This is especially useful for pagination or sampling large datasets.</p>



<h3 class="wp-block-heading"><strong>Be Cautious with LIKE and Functions</strong></h3>



<p>Avoid leading wildcards in <code>LIKE</code> and functions in <code>WHERE</code> clauses—they prevent index usage. Instead, use indexed columns and consistent casing.</p>



<h3 class="wp-block-heading"><strong>Use EXISTS Instead of IN</strong></h3>



<p><code>EXISTS</code> is often faster than <code>IN</code> because it stops scanning once a match is found. Use it for subqueries checking row existence.</p>



<h3 class="wp-block-heading"><strong>Use Appropriate Data Types</strong></h3>



<p>Choosing the right data type—like <code>TINYINT</code> over <code>INT</code> or <code>CHAR</code> over <code>VARCHAR</code>—can save space and improve performance.</p>



<h2 class="wp-block-heading">SQL Server Management Studio</h2>



<p><strong>SSMS as a Comprehensive SQL Environment</strong><br>SQL Server Management Studio (<a href="https://learn.microsoft.com/en-us/ssms/" target="_blank" rel="noopener">https://learn.microsoft.com/en-us/ssms/</a>) is a powerful, integrated environment for managing SQL Server infrastructure. It provides tools for writing, executing, and debugging SQL queries, as well as managing databases, tables, views, and stored procedures. SSMS supports both on-premises and cloud-based SQL Server instances, making it versatile for hybrid environments. Its intuitive interface includes Object Explorer for navigating server components and Query Editor for crafting and testing SQL scripts. Whether you&#8217;re a database administrator or developer, SSMS offers a unified workspace that streamlines daily tasks and enhances productivity through built-in templates, syntax highlighting, and error diagnostics.</p>



<p><strong>Security, Performance, and Monitoring Tools</strong><br>SSMS includes robust features for security management, such as configuring roles, permissions, and auditing access. It also provides performance tuning tools like the Database Engine Tuning Advisor and graphical execution plans to help identify bottlenecks. With Activity Monitor, users can track real-time server performance, view active sessions, and analyze resource usage. These tools empower teams to maintain optimal database health and ensure compliance with organizational policies. SSMS also integrates with SQL Server Agent for scheduling jobs and alerts, making it a central hub for automation and proactive monitoring across enterprise environments.</p>



<p><strong>Integration, Extensibility, and Collaboration</strong><br>SSMS supports integration with source control systems like Git, enabling versioning and collaborative development. It allows exporting and importing data via wizards, scripting database objects, and generating reports for documentation. Users can extend SSMS functionality through add-ins and connect to Azure services for cloud-based analytics and storage. Its support for multiple query windows and tabbed editing enhances multitasking, while customizable keyboard shortcuts and themes improve user experience. SSMS continues to evolve with regular updates, ensuring compatibility with the latest SQL Server features and providing a stable platform for modern data operations.</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/sql-tips">15 Essential SQL Tips You Can&#8217;t Live Without</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mietwood.com/sql-tips/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>How Works Recursive CTE in SQL Server?</title>
		<link>https://mietwood.com/recursive-cte-in-sql-server</link>
					<comments>https://mietwood.com/recursive-cte-in-sql-server#comments</comments>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Mon, 25 Aug 2025 10:03:55 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3283</guid>

					<description><![CDATA[<p>A CTE Common Table Expression is a temporary result set that you can reference within a SELECT, INSERT, UPDATE, or DELETE statement. A recursive CTE in SQL Server is a special kind of CTE that refers to itself. It&#8217;s useful for tasks like generating sequences like dates or numbers or traversing hierarchical data, e.g., org charts, folder structures etc. A recursive CTE in SQL Server consists...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/recursive-cte-in-sql-server">How Works Recursive CTE in SQL Server?</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>A <strong>CTE Common Table Expression</strong> is a temporary result set that you can reference within a <code>SELECT</code>, <code>INSERT</code>, <code>UPDATE</code>, or <code>DELETE</code> statement. A <strong>recursive CTE</strong> in SQL Server is a special kind of CTE that refers to itself. It&#8217;s useful for tasks like generating sequences like dates or numbers or traversing hierarchical data, e.g., org charts, folder structures etc.</p>



<p>A <strong>recursive CTE</strong> in SQL Server consists of:</p>



<ol class="wp-block-list">
<li><strong>Anchor member</strong> – the starting point.</li>



<li><strong>Recursive member</strong> – repeatedly executed until a condition is met.</li>
</ol>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Recursive CTE in SQL Server
-- Prevent regional settings from interfering with date interpretation
SET DATEFIRST  7,         -- Set Sunday as the first day of the week
    DATEFORMAT mdy,       -- Set date format to Month-Day-Year
    LANGUAGE   US_ENGLISH;-- Use US English for language settings

-- Declare start and cutoff dates
DECLARE @StartDate  date = '20100101'; -- Start date: Jan 1, 2010
DECLARE @CutoffDate date = DATEADD(DAY, -1, DATEADD(YEAR, 3, @StartDate));
-- Cutoff date: one day before Jan 1, 2013 (i.e., Dec 31, 2012)

-- Recursive CTE to generate a sequence of numbers from 0 to number of days between StartDate and CutoffDate
WITH seq(n) AS 
(
    SELECT 0               -- Anchor member: start with 0
    UNION ALL
    SELECT n + 1           -- Recursive member: increment n
    FROM seq
    WHERE n &lt; DATEDIFF(DAY, @StartDate, @CutoffDate)
    -- Stop when n reaches the number of days between StartDate and CutoffDate
)
SELECT n FROM seq          -- Select the generated sequence
ORDER BY n                 -- Order the result
OPTION (MAXRECURSION 0);   -- Allow unlimited recursion (default is 100)
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CTE</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SQL</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Server</span></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Prevent</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">regional</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">settings</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">interfering</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">interpretation</span></span>
<span class="line"><span style="color: #D8DEE9">SET</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DATEFIRST</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">7</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">         </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Set</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Sunday</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> the first day of the week</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">DATEFORMAT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mdy</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF">       </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Set</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">format</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">to</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Month</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">Day</span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9">Year</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">LANGUAGE</span><span style="color: #D8DEE9FF">   </span><span style="color: #D8DEE9">US_ENGLISH</span><span style="color: #81A1C1">;--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Use</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">US</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">English</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">language</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">settings</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Declare</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">start</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">and</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">cutoff</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dates</span></span>
<span class="line"><span style="color: #D8DEE9">DECLARE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D08770">@StartDate</span><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">20100101</span><span style="color: #ECEFF4">&#39;</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Start</span><span style="color: #D8DEE9FF"> date</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Jan</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2010</span></span>
<span class="line"><span style="color: #D8DEE9">DECLARE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D08770">@CutoffDate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">YEAR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Cutoff</span><span style="color: #D8DEE9FF"> date</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">one</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">day</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">before</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Jan</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2013</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">i</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">e</span><span style="color: #ECEFF4">.,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Dec</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">31</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2012</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CTE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">to</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">generate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sequence</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">of</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">numbers</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">to</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">number</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">of</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">days</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">between</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">and</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CutoffDate</span></span>
<span class="line"><span style="color: #D8DEE9">WITH</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">seq</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">               </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Anchor</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">member</span><span style="color: #D8DEE9FF">: </span><span style="color: #D8DEE9">start</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">with</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">UNION</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ALL</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #D8DEE9FF">           </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">member</span><span style="color: #D8DEE9FF">: </span><span style="color: #D8DEE9">increment</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seq</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">WHERE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEDIFF</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">CutoffDate</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Stop</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">when</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">reaches</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">the</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">number</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">of</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">days</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">between</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">and</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CutoffDate</span></span>
<span class="line"><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seq</span><span style="color: #D8DEE9FF">          </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Select</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">the</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">generated</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">sequence</span></span>
<span class="line"><span style="color: #D8DEE9">ORDER</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">BY</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">                 </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Order</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">the</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">result</span></span>
<span class="line"><span style="color: #88C0D0">OPTION</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">MAXRECURSION</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Allow</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">unlimited</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">recursion</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">is</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p>Recursive CTE in SQL Server.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading" id="introduction">Data table for BI</h3>



<p>In business intelligence (BI) and data warehousing, a <strong>date dimension table</strong> is a foundational component that enables powerful time-based analysis. This SQL script demonstrates how to dynamically generate a comprehensive date dimension using a recursive Common Table Expression (CTE). Starting from a defined <code>StartDate</code>, it builds a sequence of dates up to a <code>CutoffDate</code>, enriching each date with attributes such as day name, month, quarter, week number, and weekend flag. This structure supports flexible filtering, grouping, and visualization in BI tools like Power BI, Tableau, or SQL Server Reporting Services (SSRS), and ensures consistent date logic across reports and dashboards.</p>



<h2 class="wp-block-heading">Recursive CTE in SQL Server</h2>



<ol class="wp-block-list">
<li><strong>Translate the generated numbers into actual dates</strong>.</li>



<li><strong>Create a date dimension table</strong> suitable for use in BI tools like Power BI or Tableau.</li>
</ol>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Recursive CTE in SQL Server
-- Regional settings
SET DATEFIRST  7,
    DATEFORMAT mdy,
    LANGUAGE   US_ENGLISH;

-- Define date range
DECLARE @StartDate  date = '20100101';
DECLARE @CutoffDate date = DATEADD(DAY, -1, DATEADD(YEAR, 3, @StartDate));

-- Recursive CTE to generate date dimension
WITH seq(n) AS 
(
    SELECT 0
    UNION ALL
    SELECT n + 1
    FROM seq
    WHERE n &lt; DATEDIFF(DAY, @StartDate, @CutoffDate)
),
DateDimension AS
(
    SELECT 
        DATEADD(DAY, n, @StartDate) AS Date,
        DATENAME(WEEKDAY, DATEADD(DAY, n, @StartDate)) AS DayName,
        DATEPART(WEEKDAY, DATEADD(DAY, n, @StartDate)) AS DayOfWeek,
        DATEPART(DAY, DATEADD(DAY, n, @StartDate)) AS Day,
        DATEPART(MONTH, DATEADD(DAY, n, @StartDate)) AS Month,
        DATENAME(MONTH, DATEADD(DAY, n, @StartDate)) AS MonthName,
        DATEPART(YEAR, DATEADD(DAY, n, @StartDate)) AS Year,
        DATEPART(QUARTER, DATEADD(DAY, n, @StartDate)) AS Quarter,
        DATEPART(WEEK, DATEADD(DAY, n, @StartDate)) AS WeekOfYear,
        CASE 
            WHEN DATEPART(WEEKDAY, DATEADD(DAY, n, @StartDate)) IN (1, 7) THEN 1
            ELSE 0
        END AS IsWeekend
    FROM seq
)
SELECT * FROM DateDimension
ORDER BY Date
OPTION (MAXRECURSION 0);
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CTE</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SQL</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Server</span></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Regional</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">settings</span></span>
<span class="line"><span style="color: #D8DEE9">SET</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DATEFIRST</span><span style="color: #D8DEE9FF">  </span><span style="color: #B48EAD">7</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">DATEFORMAT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mdy</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">LANGUAGE</span><span style="color: #D8DEE9FF">   </span><span style="color: #D8DEE9">US_ENGLISH</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Define</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">range</span></span>
<span class="line"><span style="color: #D8DEE9">DECLARE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D08770">@StartDate</span><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">20100101</span><span style="color: #ECEFF4">&#39;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9">DECLARE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D08770">@CutoffDate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">YEAR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">))</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CTE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">to</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">generate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">date</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dimension</span></span>
<span class="line"><span style="color: #D8DEE9">WITH</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">seq</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">UNION</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ALL</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seq</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">WHERE</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEDIFF</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">CutoffDate</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9">DateDimension</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span></span>
<span class="line"><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Date</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATENAME</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEKDAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DayName</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEKDAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DayOfWeek</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Day</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MONTH</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Month</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATENAME</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MONTH</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MonthName</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">YEAR</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Year</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">QUARTER</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Quarter</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEK</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">WeekOfYear</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">CASE</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEPART</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEKDAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATEADD</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">DAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">n</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> @</span><span style="color: #D8DEE9">StartDate</span><span style="color: #D8DEE9FF">)) </span><span style="color: #88C0D0">IN</span><span style="color: #D8DEE9FF"> (</span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">7</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #D8DEE9">ELSE</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">END</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">IsWeekend</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">seq</span></span>
<span class="line"><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DateDimension</span></span>
<span class="line"><span style="color: #D8DEE9">ORDER</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">BY</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Date</span></span>
<span class="line"><span style="color: #88C0D0">OPTION</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">MAXRECURSION</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<p>Trad more <a href="https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/" target="_blank" rel="noopener">here</a> and <a href="https://mietwood.com/how-to-set-the-first-day-of-week-datefirst">How To Set The First Day of Week DATEFIRST</a></p>



<h2 class="wp-block-heading">Next Steps</h2>



<ul class="wp-block-list">
<li>Add fiscal year columns</li>



<li>Add holiday flags (if you provide a list)</li>



<li>Localize day/month names to Polish if needed</li>
</ul>



<h3 class="wp-block-heading">Fiscal Year Columns</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Recursive CTE in SQL Server
-- Assuming fiscal year starts in April
SELECT
    Date,
    CASE 
        WHEN MONTH(Date) >= 4 THEN YEAR(Date)
        ELSE YEAR(Date) - 1
    END AS FiscalYear,
    CASE 
        WHEN MONTH(Date) BETWEEN 4 AND 6 THEN 1
        WHEN MONTH(Date) BETWEEN 7 AND 9 THEN 2
        WHEN MONTH(Date) BETWEEN 10 AND 12 THEN 3
        ELSE 4
    END AS FiscalQuarter
FROM DateDimension
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CTE</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SQL</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Server</span></span>
<span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Assuming</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fiscal</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">year</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">starts</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">April</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">Date</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">CASE</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MONTH</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">&gt;=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">YEAR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">ELSE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">YEAR</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">END</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FiscalYear</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">CASE</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MONTH</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">BETWEEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AND</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">6</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MONTH</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">BETWEEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">7</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AND</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">MONTH</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">BETWEEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AND</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">12</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">ELSE</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">END</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">FiscalQuarter</span></span>
<span class="line"><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DateDimension</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Holiday Flags</h3>



<p>It requires a holiday list. Assuming you have a table called <code>HolidayList</code> with a column <code>HolidayDate</code>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Recursive CTE in SQL Server
SELECT
    d.*,
    CASE 
        WHEN h.HolidayDate IS NOT NULL THEN 1
        ELSE 0
    END AS IsHoliday
FROM DateDimension d
LEFT JOIN HolidayList h ON d.Date = h.HolidayDate
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">Recursive</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">CTE</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">SQL</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Server</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">.</span><span style="color: #81A1C1">*</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">CASE</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">h</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">HolidayDate</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">IS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NOT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">NULL</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">ELSE</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">END</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">IsHoliday</span></span>
<span class="line"><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DateDimension</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span></span>
<span class="line"><span style="color: #D8DEE9">LEFT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">JOIN</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">HolidayList</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">h</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ON</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">d</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">h</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">HolidayDate</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Localize Day/Month Names to Polish</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>SELECT
    Date,
    CASE DATENAME(WEEKDAY, Date)
        WHEN 'Monday' THEN 'Poniedziałek'
        WHEN 'Tuesday' THEN 'Wtorek'
        WHEN 'Wednesday' THEN 'Środa'
        WHEN 'Thursday' THEN 'Czwartek'
        WHEN 'Friday' THEN 'Piątek'
        WHEN 'Saturday' THEN 'Sobota'
        WHEN 'Sunday' THEN 'Niedziela'
    END AS DayNamePL,
    CASE DATENAME(MONTH, Date)
        WHEN 'January' THEN 'Styczeń'
        WHEN 'February' THEN 'Luty'
        WHEN 'March' THEN 'Marzec'
        WHEN 'April' THEN 'Kwiecień'
        WHEN 'May' THEN 'Maj'
        WHEN 'June' THEN 'Czerwiec'
        WHEN 'July' THEN 'Lipiec'
        WHEN 'August' THEN 'Sierpień'
        WHEN 'September' THEN 'Wrzesień'
        WHEN 'October' THEN 'Październik'
        WHEN 'November' THEN 'Listopad'
        WHEN 'December' THEN 'Grudzień'
    END AS MonthNamePL
FROM DateDimension
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">SELECT</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">Date</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">CASE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATENAME</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">WEEKDAY</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Monday</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Poniedziałek</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Tuesday</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Wtorek</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Wednesday</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Środa</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Thursday</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Czwartek</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Friday</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Piątek</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Saturday</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Sobota</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Sunday</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Niedziela</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">END</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DayNamePL</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">CASE</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">DATENAME</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">MONTH</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Date</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">January</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Styczeń</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">February</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Luty</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">March</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Marzec</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">April</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Kwiecień</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">May</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Maj</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">June</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Czerwiec</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">July</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Lipiec</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">August</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Sierpień</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">September</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Wrzesień</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">October</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Październik</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">November</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Listopad</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">WHEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">December</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">THEN</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Grudzień</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">END</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">AS</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">MonthNamePL</span></span>
<span class="line"><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">DateDimension</span></span>
<span class="line"></span></code></pre></div>



<p>This extended SQL script builds a robust <strong>date dimension table</strong> tailored for business intelligence applications. Starting with a recursive CTE to generate a sequence of dates, it enriches each entry with key calendar attributes such as day names, month names, quarters, and weekend flags. Additional enhancements include fiscal year logic, holiday indicators (based on a provided list), and localization of day and month names to Polish. These features ensure the table supports flexible, localized, and context-aware time-based analysis in tools like Power BI, Tableau, or SQL Server Reporting Services.</p>



<p></p>
<p>The post <a rel="nofollow" href="https://mietwood.com/recursive-cte-in-sql-server">How Works Recursive CTE in SQL Server?</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mietwood.com/recursive-cte-in-sql-server/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>10 Tips How To Make SQL Lighter</title>
		<link>https://mietwood.com/10-tips-how-to-make-sql-lighter</link>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Tue, 12 Aug 2025 09:15:29 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3253</guid>

					<description><![CDATA[<p>To optimize your queries for better performance and a lighter load on the database, consider the following 10 Tips How To Make SQL Lighter. SQL queries can be heavy and slow for various reasons, including inefficient data retrieval, poor indexing, and improper joins. Reduce records in reference. Instead of query 1 which is quite heavy...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/10-tips-how-to-make-sql-lighter">10 Tips How To Make SQL Lighter</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>To optimize your queries for better performance and a lighter load on the database, consider the following 10 Tips How To Make SQL Lighter. SQL queries can be heavy and slow for various reasons, including inefficient data retrieval, poor indexing, and improper joins. </p>



<p>Reduce records in reference. Instead of query 1 which is quite heavy you can use query 2 &#8211; much lighter.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>-- query 1
SELECT a.ProductId, p.&#91;index&#93; ProdIdx, p.&#91;Name&#93;, p.&#91;PriceDefault&#93;,
 isNull(pp.category_top,'Cat_null') Category_top, COUNT(*) Prod_bom_count
  
    FROM &#91;DBProductAttribute&#93; a with (nolock)
        left join &#91;DBProduct&#93; p with (nolock) on p.Id=a.ProductId
        left join &#91;DB_Products&#93; pp with (nolock) on pp.ProductId=a.ProductId
    where a.&#91;name&#93;='bom'
group by a.ProductId, p.&#91;index&#93;, p.&#91;Name&#93;, p.&#91;PriceDefault&#93;, isNull(pp.category_top,'Cat_null')</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">query</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">index</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">ProdIdx</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Name</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">PriceDefault</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">isNull</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">pp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">category_top</span><span style="color: #ECEFF4">,</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Cat_null</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">Category_top</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">COUNT</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">Prod_bom_count</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">DBProductAttribute</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">nolock</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">join</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">DBProduct</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">nolock</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">on</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Id</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">join</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">DB_Products</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">pp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">nolock</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">on</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">where</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">bom</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9">group</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">by</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">index</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Name</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">PriceDefault</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">isNull</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">pp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">category_top</span><span style="color: #ECEFF4">,</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Cat_null</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">)</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>-- query 2
SELECT a.ProductId, p.&#91;index&#93; ProdIdx, p.&#91;Name&#93;, p.&#91;PriceDefault&#93;,
 isNull(pp.category_top,'Cat_null') Category_top, COUNT(*) Prod_bom_count
  
    FROM &#91;DBProductAttribute&#93; a with (nolock)
        left join &#91;DBProduct&#93; p with (nolock) on p.Id=a.ProductId
        left join &#91;DB_Products&#93; pp with (nolock) on pp.ProductId=a.ProductId
    where a.&#91;name&#93;='bom'
group by a.ProductId, p.&#91;index&#93;, p.&#91;Name&#93;, p.&#91;PriceDefault&#93;, isNull(pp.category_top,'Cat_null')</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">--</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">query</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2</span></span>
<span class="line"><span style="color: #D8DEE9">SELECT</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">index</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">ProdIdx</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Name</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">PriceDefault</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">isNull</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">pp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">category_top</span><span style="color: #ECEFF4">,</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Cat_null</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">Category_top</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">COUNT</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">*</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">Prod_bom_count</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">FROM</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">DBProductAttribute</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">nolock</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">join</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">DBProduct</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">nolock</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">on</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Id</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">left</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">join</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">DB_Products</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">pp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">nolock</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">on</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">pp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">where</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">bom</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9">group</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">by</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ProductId</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">index</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Name</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">PriceDefault</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">isNull</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">pp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">category_top</span><span style="color: #ECEFF4">,</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">Cat_null</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">)</span></span></code></pre></div>



<h2 class="wp-block-heading">10 Tips How To Make SQL Lighter</h2>



<h3 class="wp-block-heading">1. <strong>Select Only What You Need</strong></h3>



<p>Instead of using <code>SELECT *</code>, specify the exact columns you need. This reduces the amount of data transferred from the database server to the application, lowering network traffic and memory usage.</p>



<p>SQL</p>



<pre class="wp-block-code"><code>-- Bad
SELECT * FROM employees;

-- Good
SELECT employee_id, first_name, last_name FROM employees;
</code></pre>



<h3 class="wp-block-heading">2. <strong>Use Joins Efficiently</strong></h3>



<p>Use the most appropriate join type for your needs. For example, use <strong><code>INNER JOIN</code></strong> when you only need rows with matching values in both tables. Avoid cross joins if possible, as they produce the Cartesian product of the two tables, which can be massive.</p>



<h3 class="wp-block-heading">3. <strong>Filter Data Early</strong>. 10 Tips How To Make SQL Lighter.</h3>



<p>Use the <strong><code>WHERE</code></strong> clause to filter data as early as possible. This reduces the number of rows processed by subsequent operations like joins or aggregations.</p>



<p>SQL</p>



<pre class="wp-block-code"><code>-- Bad
SELECT first_name, last_name, salary
FROM employees
WHERE department_id IN (
    SELECT department_id FROM departments WHERE location = 'New York'
);

-- Good (filtering early)
SELECT e.first_name, e.last_name, e.salary
FROM employees AS e
JOIN departments AS d ON e.department_id = d.department_id
WHERE d.location = 'New York';
</code></pre>



<h3 class="wp-block-heading">4. <strong>Use Indexes</strong></h3>



<p>Indexes are crucial for speeding up data retrieval. Ensure that columns used in <strong><code>WHERE</code></strong> clauses, <strong><code>JOIN</code></strong> conditions, and <strong><code>ORDER BY</code></strong> clauses are indexed. However, be mindful that too many indexes can slow down <code>INSERT</code>, <code>UPDATE</code>, and <code>DELETE</code> operations.</p>



<h3 class="wp-block-heading">5. <strong>Avoid <code>Subqueries</code> in the <code>WHERE</code> Clause</strong></h3>



<p>Correlated subqueries can be very slow because they execute once for each row in the outer query. It&#8217;s often more efficient to rewrite them as <strong><code>JOINs</code></strong>.</p>



<h3 class="wp-block-heading">6. <strong>Use <code>UNION ALL</code> Instead of <code>UNION</code></strong></h3>



<p><strong><code>UNION</code></strong> removes duplicate rows, which is an expensive operation. If you know there are no duplicates or you don&#8217;t need to remove them, use <strong><code>UNION ALL</code></strong> for better performance.</p>



<h3 class="wp-block-heading">7. <strong>Limit Your Results</strong></h3>



<p>When fetching a large dataset, use <strong><code>LIMIT</code></strong> (or <code>TOP</code> in SQL Server) to restrict the number of rows returned. This is especially useful for pagination or when you only need a sample of the data. 10 Tips How To Make SQL Lighter.</p>



<h3 class="wp-block-heading">8. <strong>Be Cautious with <code>LIKE</code> and <code>Functions</code></strong></h3>



<p>Using the <strong><code>LIKE</code></strong> operator with a leading wildcard (<code>%</code>) or applying functions to columns in a <strong><code>WHERE</code></strong> clause can prevent the database from using an index. Instead of <code>'</code>%value<code>'</code>, use <code>'</code>value%<code>'</code>. Avoid <code>WHERE UPPER(column) = 'VALUE'</code>, and try to store data in a consistent case.</p>



<h3 class="wp-block-heading">9. <strong>Use <code>EXISTS</code> Instead of <code>IN</code></strong></h3>



<p>For subqueries that check for the existence of rows, <strong><code>EXISTS</code></strong> is often faster than <strong><code>IN</code></strong> because <code>EXISTS</code> stops scanning as soon as it finds a match, whereas <code>IN</code> might scan the entire subquery result set.</p>



<h3 class="wp-block-heading">10. <strong>Use <code>Appropriate Data Types</code></strong></h3>



<p>Choosing the right data type for your columns can save storage space and improve performance. For example, using <code>TINYINT</code> instead of <code>INT</code> for a small numerical range, or <code>CHAR</code> instead of <code>VARCHAR</code> if the length is fixed.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="354" height="460" src="https://mietwood.com/wp-content/uploads/2025/08/image.jpg" alt="10 Tips How To Make SQL Lighter" class="wp-image-3255" srcset="https://mietwood.com/wp-content/uploads/2025/08/image.jpg 354w, https://mietwood.com/wp-content/uploads/2025/08/image-231x300.jpg 231w" sizes="(max-width: 354px) 100vw, 354px" /><figcaption class="wp-element-caption">Column&#8217;s types in MS SQL Management Studio</figcaption></figure>



<p>Some tips consulted with <a href="https://gemini.google.com" target="_blank" rel="noopener">https://gemini.google.com</a></p>



<p>More sql tips <a href="https://mietwood.com/category/sql">here</a></p>



<p></p>
<p>The post <a rel="nofollow" href="https://mietwood.com/10-tips-how-to-make-sql-lighter">10 Tips How To Make SQL Lighter</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Python for analysts most important datetime functions</title>
		<link>https://mietwood.com/python-for-analysts-most-important-datetime-functions</link>
					<comments>https://mietwood.com/python-for-analysts-most-important-datetime-functions#comments</comments>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Sun, 20 Jul 2025 16:18:38 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[data science]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3211</guid>

					<description><![CDATA[<p>Python’s powerful date and time functions using the datetime and pandas libraries gives you a robust date table ready for Power BI and other business intelligence and analytical tools. Python for analysts most important datetime functions. Mastering Date and Time Functions in Python for Power BI Date Tables When working with Power BI, a well-structured...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/python-for-analysts-most-important-datetime-functions">Python for analysts most important datetime functions</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Python’s powerful <strong>date and time functions</strong> using the <code>datetime</code> and <code>pandas</code> libraries gives you a robust date table ready for Power BI and other business intelligence and analytical tools. Python for analysts most important datetime functions.</p>



<h2 class="wp-block-heading" id="masteringdateandtimefunctionsinpythonforpowerbidatetables">Mastering Date and Time Functions in Python for Power BI Date Tables</h2>



<p>When working with Power BI, a well-structured <strong>Date Table</strong> is essential for time intelligence calculations like YTD, QTD, MTD, and custom period comparisons. While Power BI has built-in date table features, using <strong>Python</strong> to generate a custom date table gives you full control over the structure, granularity, and logic.</p>



<p>In this post, we’ll explore Python’s powerful <strong>date and time functions</strong> using the <code>datetime</code> and <code>pandas</code> libraries, and show how to create a robust date table ready for Power BI.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="1pythondateandtimebasics">Python for analyst – date and time functions &#8211; basics</h2>



<p>Python provides the <a href="https://docs.python.org/3/library/datetime.html" target="_blank" rel="noopener"><code>datetime</code> module</a> to work with dates and times. Here&#8217;s a quick overview:</p>



<pre class="wp-block-code"><code>from datetime import datetime, timedelta, date

# Current date and time
now = datetime.now()
print("Now:", now)

# Just the date
today = date.today()
print("Today:", today)

# Add 7 days
next_week = today + timedelta(days=7)
print("Next week:", next_week)

# Subtract 30 days
last_month = today - timedelta(days=30)
print("30 days ago:", last_month)
</code></pre>



<p>These functions are the foundation for generating date ranges and calculating custom columns like fiscal periods or holidays. Python for analysts most important datetime functions.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="2creatingadaterangewithpandas">Creating a Date Range with Pandas</h2>



<p>To build a date table, we need a continuous range of dates. <code>pandas.date_range()</code> is perfect for this:</p>



<pre class="wp-block-code"><code>import pandas as pd

# Generate a date range from 2020 to 2030
date_range = pd.date_range(start='2020-01-01', end='2030-12-31', freq='D')
df = pd.DataFrame({'Date': date_range})
</code></pre>



<p>This gives us a DataFrame with one row per day — the backbone of our date table.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="3enrichingthedatetable">Enriching the Date Table</h2>



<p>Now let’s add useful columns for Power BI:</p>



<pre class="wp-block-code"><code>df&#91;'Year'] = df&#91;'Date'].dt.year
df&#91;'Month'] = df&#91;'Date'].dt.month
df&#91;'MonthName'] = df&#91;'Date'].dt.strftime('%B')
df&#91;'Quarter'] = df&#91;'Date'].dt.quarter
df&#91;'Day'] = df&#91;'Date'].dt.day
df&#91;'Weekday'] = df&#91;'Date'].dt.weekday + 1  # Monday = 1
df&#91;'WeekdayName'] = df&#91;'Date'].dt.strftime('%A')
df&#91;'IsWeekend'] = df&#91;'Weekday'].isin(&#91;6, 7])
df&#91;'Week'] = df&#91;'Date'].dt.isocalendar().week
df&#91;'DayOfYear'] = df&#91;'Date'].dt.dayofyear
</code></pre>



<p>These columns allow for slicing and dicing your data in Power BI by year, month, weekday, and more.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="4fiscalcalendarsupport">Fiscal Calendar Support</h2>



<p>Many businesses use fiscal calendars that don’t align with the calendar year. Here’s how to add a fiscal year starting in July:</p>



<pre class="wp-block-code"><code>df&#91;'FiscalYear'] = df&#91;'Date'].apply(lambda x: x.year if x.month &lt; 7 else x.year + 1)
df&#91;'FiscalMonth'] = df&#91;'Date'].apply(lambda x: x.month - 6 if x.month &gt;= 7 else x.month + 6)
df&#91;'FiscalQuarter'] = ((df&#91;'FiscalMonth'] - 1) // 3) + 1
</code></pre>



<p>This logic adjusts the fiscal year, month, and quarter based on a July start. Python for analysts most important datetime functions</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="5flagsfortimeintelligence">5. Flags for Time Intelligence</h2>



<p>Power BI benefits from flags that simplify DAX calculations:</p>



<pre class="wp-block-code"><code>today = pd.to_datetime('today').normalize()

df&#91;'IsToday'] = df&#91;'Date'] == today
df&#91;'IsCurrentMonth'] = (df&#91;'Date'].dt.month == today.month) &amp; (df&#91;'Date'].dt.year == today.year)
df&#91;'IsCurrentYear'] = df&#91;'Date'].dt.year == today.year
</code></pre>



<p>You can also add flags for holidays, fiscal periods, or custom business logic. Python for analysts most important datetime functions</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="6exportingtocsvforpowerbi">Exporting to CSV for Power BI</h2>



<p>Once your date table is ready, export it:</p>



<pre class="wp-block-code"><code>df.to_csv('DateTable.csv', index=False)
</code></pre>



<p>You can now import this CSV into Power BI as a static date table.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="7sampleoutput">7. Sample Output</h2>



<p>Here’s a preview of what your date table might look like:</p>



<figure class="wp-block-table aligncenter is-style-regular has-small-font-size"><table><thead><tr><th></th><th></th><th class="has-text-align-center" data-align="center"></th><th></th><th></th><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td>2025-01-01</td><td>2025</td><td class="has-text-align-center" data-align="center">1</td><td>January</td><td>1</td><td>Wednesday</td><td>False</td><td>2025</td><td>False</td></tr><tr><td>2025-07-01</td><td>2025</td><td class="has-text-align-center" data-align="center">7</td><td>July</td><td>3</td><td>Tuesday</td><td>False</td><td>2026</td><td>False</td></tr><tr><td>2025-12-25</td><td>2025</td><td class="has-text-align-center" data-align="center">12</td><td>December</td><td>4</td><td>Thursday</td><td>False</td><td>2026</td><td>False</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Pandas to_datetime() function</h2>



<p>Python for analysts most important datetime functions &#8211; pandas</p>



<pre class="wp-block-code"><code> #   Column                  Non-Null Count  Dtype         
---  ------                  --------------  -----         
 0   CustomerId              13483 non-null  int64         
 1   Dt_first_rew_income     2987 non-null   datetime64&#91;ns]
 2   Dt_first_purchase       13483 non-null  object        
 3   Dt_last_purchase        13483 non-null  object        

df_cust&#91;'Dt_first_purchase'] = pd.to_datetime(df_cust&#91;'Dt_first_purchase'],format="yyyy-mm-dd")
df_cust&#91;'Dt_last_purchase'] = pd.to_datetime(df_cust&#91;'Dt_last_purchase'],format="yyyy-mm-dd")

 #   Column                  Non-Null Count  Dtype         
---  ------                  --------------  -----         
 0   CustomerId              13483 non-null  int64         
 1   Dt_first_rew_income     2987 non-null   datetime64&#91;ns]
 2   Dt_first_purchase       13483 non-null  datetime64&#91;ns]
 3   Dt_last_purchase        13483 non-null  datetime64&#91;ns]</code></pre>



<h2 class="wp-block-heading" id="8advancedtips">Advanced Tips</h2>



<ul class="wp-block-list">
<li><strong>Holidays</strong>: Use external APIs or CSVs to mark public holidays.</li>



<li><strong>Week Start</strong>: Adjust <code>Weekday</code> to match your locale (e.g., Monday vs. Sunday).</li>



<li><strong>Time Zones</strong>: Use <code>pytz</code> or <code>zoneinfo</code> for timezone-aware datetime handling.</li>



<li><strong>Dynamic Updates</strong>: Automate the script to regenerate the table monthly or yearly.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Certainly! Here&#8217;s a concise <strong>400-word post</strong> on <strong>SQL Date and Time Functions</strong>, with examples, tailored for building a <strong>Date Table in Power BI</strong>:</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="sqldateandtimefunctionsforpowerbidatetables">SQL Date and Time Functions for Power BI Date Tables</h2>



<p>When building reports in Power BI, a comprehensive <strong>Date Table</strong> is essential for enabling time-based calculations like YTD, MTD, and custom period comparisons. While Power BI can auto-generate a date table, using <strong>SQL</strong> to create one gives you full control over its structure and logic.</p>



<p>Let’s explore key <strong>SQL Server date and time functions</strong> and how to use them to build a robust date table.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="1generatingadaterange">1. Generating a Date Range</h2>



<p>To create a date table, you need a continuous range of dates. In SQL Server, you can use a loop or a recursive CTE:</p>



<pre class="wp-block-code"><code>DECLARE @StartDate DATE = '2020-01-01';
DECLARE @EndDate DATE = '2030-12-31';

WITH DateCTE AS (
    SELECT @StartDate AS DateValue
    UNION ALL
    SELECT DATEADD(DAY, 1, DateValue)
    FROM DateCTE
    WHERE DateValue &lt; @EndDate
)
SELECT * INTO DateTable FROM DateCTE
OPTION (MAXRECURSION 32767);

select * from DateTable
</code></pre>



<p>Here the example </p>



<figure class="wp-block-image size-full"><img decoding="async" width="440" height="575" src="https://mietwood.com/wp-content/uploads/2025/07/image-17.jpg" alt="Python for analysts most important datetime functions in sql" class="wp-image-3213" srcset="https://mietwood.com/wp-content/uploads/2025/07/image-17.jpg 440w, https://mietwood.com/wp-content/uploads/2025/07/image-17-230x300.jpg 230w" sizes="(max-width: 440px) 100vw, 440px" /><figcaption class="wp-element-caption">Python for analysts most important datetime functions in sql</figcaption></figure>



<p>This creates a table with one row per day between 2020 and 2030.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="2addingdateattributes">2. Adding Date Attributes</h2>



<p>Once you have the base dates, enrich them with useful columns:</p>



<pre class="wp-block-code"><code>ALTER TABLE DateTable ADD 
    Year INT,
    Month INT,
    MonthName VARCHAR(20),
    Quarter INT,
    Weekday INT,
    WeekdayName VARCHAR(20);

UPDATE DateTable
SET 
    Year = YEAR(DateValue),
    Month = MONTH(DateValue),
    MonthName = DATENAME(MONTH, DateValue),
    Quarter = DATEPART(QUARTER, DateValue),
    Weekday = DATEPART(WEEKDAY, DateValue),
    WeekdayName = DATENAME(WEEKDAY, DateValue);
</code></pre>



<p>These columns allow for flexible filtering and grouping in Power BI.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="3fiscalcalendarandflags">3. Fiscal Calendar and Flags</h2>



<p>You can also add fiscal logic and flags:</p>



<pre class="wp-block-code"><code>ALTER TABLE DateTable ADD FiscalYear INT;

UPDATE DateTable
SET FiscalYear = CASE 
    WHEN MONTH(DateValue) &gt;= 7 THEN YEAR(DateValue) + 1
    ELSE YEAR(DateValue)
END;
</code></pre>



<p>Add flags like <code>IsWeekend</code>, <code>IsToday</code>, or <code>IsCurrentMonth</code> to simplify DAX expressions.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p></p>



<h2 class="wp-block-heading" id="conclusion">Conclusion</h2>



<p>Python offers a flexible and powerful way to create a <strong>custom date table</strong> for Power BI. With just a few lines of code, you can generate a rich dataset that supports advanced time intelligence and reporting needs.</p>



<p>Whether you&#8217;re working with fiscal calendars, custom flags, or multilingual support, Python gives you the tools to tailor your date table exactly to your business requirements.</p>



<p>SQL’s date and time functions like <code>DATEADD</code>, <code>DATEPART</code>, <code>DATENAME</code>, and <code>YEAR</code> are powerful tools for building a custom date table. Once created, export it to Power BI or use it as a view for dynamic reporting.</p>



<p>Would you like a ready-to-run SQL script for a complete date table?</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Find more resources in our course of <a href="https://mietwood.com/programowanie-zaawansowane-w-analityce">Advanced programming for business analysts</a></p>
<p>The post <a rel="nofollow" href="https://mietwood.com/python-for-analysts-most-important-datetime-functions">Python for analysts most important datetime functions</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mietwood.com/python-for-analysts-most-important-datetime-functions/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Moving average in SQL</title>
		<link>https://mietwood.com/moving-average-in-sql</link>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Mon, 07 Jul 2025 09:33:18 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[data science]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3155</guid>

					<description><![CDATA[<p>The post will explore two methods for creating a moving average in SQL Server. The older methods using linking and correlation queries and a new using widows functions in SQL Server. Moving average in SQL Post is based on: Calculate a Moving Average with T-SQL Windowing Functions Indexing moving average &#8211; old approach Statistics Another...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/moving-average-in-sql">Moving average in SQL</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The post will explore two methods for creating a moving average in SQL Server.  The older methods using linking and correlation queries and a new using widows functions in SQL Server. Moving average in SQL</p>



<p>Post is based on: <a href="https://www.mssqltips.com/sqlservertip/8124/calculate-a-moving-average-with-t-sql-windowing-functions/" target="_blank" rel="noopener">Calculate a Moving Average with T-SQL Windowing Functions</a></p>



<pre class="wp-block-code"><code>-- test table
-- mssqltips.com
DROP TABLE IF EXISTS dbo.BigWeightTracker;
GO

CREATE TABLE dbo.BigWeightTracker
(
    Id INT IDENTITY(1, 1) NOT NULL,
    UserId INT NOT NULL,
    Pounds Decimal(10, 2) NOT NULL,
    DateRecorded DATE NOT NULL,
    CONSTRAINT PK_BigWeightTracker_Id
        PRIMARY KEY CLUSTERED (Id)
);
GO

DECLARE @StartDate DATE = '2022-01-01';
DECLARE @EndDate DATE = '2023-12-31';

WITH 
 Users AS (SELECT TOP 60
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS UserId
    -- select top 100 *
    FROM sys.all_columns AS s1
   ),
 Dates AS (
    SELECT @StartDate AS Date
    UNION ALL
    SELECT DATEADD(DAY, 1, Date) AS Date FROM Dates  WHERE Date &lt; @EndDate
   )
--select * from Dates, ale insert działa bez tego ograniczenia

INSERT INTO dbo.BigWeightTracker
(
    UserId,
    DateRecorded,
    Pounds
)
SELECT u.UserId,
       d.Date,
       (ABS(CHECKSUM(NEWID()) % (220 - 170 + 1)) + 170) AS Weight
FROM Users u
    CROSS JOIN Dates d
OPTION (MAXRECURSION 0);
GO

-- koniec tworzenia tabeli -----------</code></pre>



<p>Indexing</p>



<pre class="wp-block-code"><code>-- indexing
DROP INDEX IF EXISTS IX_BigWeightTracker_Average ON dbo.BigWeightTracker;

CREATE NONCLUSTERED INDEX IX_BigWeightTracker_Average
ON dbo.BigWeightTracker
(
    UserId,
    DateRecorded ASC
)
INCLUDE (Pounds);
GO</code></pre>



<p>moving average &#8211; old approach</p>



<pre class="wp-block-code"><code>-- moving avg - old aproach
-- mssqltips.com
SET STATISTICS TIME, IO ON;
SELECT t1.UserId,
       t1.DateRecorded,
       t1.Pounds,
       CASE
           WHEN COUNT(t2.Pounds) &lt; 7 THEN
               NULL
           ELSE
               AVG(t2.Pounds)
       END AS &#91;7DayMovingAverage]
FROM dbo.BigWeightTracker t1
    INNER JOIN dbo.BigWeightTracker t2
        ON t2.DateRecorded
           BETWEEN DATEADD(DAY, -6, t1.DateRecorded) AND t1.DateRecorded
           AND t1.UserId = t2.UserId
GROUP BY t1.UserId,
         t1.DateRecorded,
         t1.Pounds
ORDER BY t1.UserId,
         t1.DateRecorded;
SET STATISTICS TIME, IO OFF;
GO</code></pre>



<p>Statistics</p>



<pre class="wp-block-code"><code>(438000 rows affected)
Tabela „BigWeightTracker”. 
Liczba skanowań: 10, odczyty logiczne: 3310, odczyty z wyprzedzeniem: 1542.

Tabela „Worktable”. Liczba skanowań: 600, odczyty logiczne: 2634596, odczyty z wyprzedzeniem: 10957.
SQL Server — czasy wykonywania:
  Czas procesora CPU = 94376 ms; upłynęło czasu = 27683 ms.</code></pre>



<p>Another way to write this query is to use a <a href="https://www.mssqltips.com/sqlservertip/6037/sql-server-uncorrelated-and-correlated-subquery/" target="_blank" rel="noreferrer noopener">correlated subquery</a> (podzapytanie). Based on the performance metrics, this approach still results in a high number of logical reads and scans with about the same execution time. Moving average in SQL.</p>



<pre class="wp-block-code"><code>-- qwerenda z podzapytaniem
-- mssqltips.com
SET STATISTICS TIME, IO ON;
SELECT t1.UserId,
       t1.DateRecorded,
       t1.Pounds,
       (
           SELECT CASE
                      WHEN COUNT(t2.Pounds) &lt; 7 THEN
                          NULL
                      ELSE
                          AVG(t2.Pounds)
                  END
           FROM BigWeightTracker t2
           WHERE t2.DateRecorded
                 BETWEEN DATEADD(DAY, -6, t1.DateRecorded) AND t1.DateRecorded
                 AND t1.UserId = t2.UserId
       ) AS &#91;7DayMovingAverage]
FROM dbo.BigWeightTracker t1
ORDER BY t1.UserId,
         t1.DateRecorded;
SET STATISTICS TIME, IO OFF;</code></pre>



<p>Statystyka</p>



<pre class="wp-block-code"><code>(438000 rows affected)
Tabela „BigWeightTracker”. Liczba skanowań: 6, odczyty logiczne: 3232, odczyty fizyczne: 3, odczyty z wyprzedzeniem: 1573.
Tabela „Worktable”. Liczba skanowań: 1314000, odczyty logiczne: 6884158.
 SQL Server — czasy wykonywania:
  Czas procesora CPU = 8593 ms; upłynęło czasu = 5162 ms.</code></pre>



<h2 class="wp-block-heading">Window functions</h2>



<p>Microsoft introduced&nbsp;<a href="https://www.mssqltips.com/sqlservertip/6738/sql-window-functions-in-sql-server/" target="_blank" rel="noreferrer noopener">window functions</a>&nbsp;in SQL Server 2005, but added new and improved options in SQL Server 2012.  A few functions to use with windowing include:</p>



<ul class="wp-block-list">
<li><strong>ROW_NUMBER</strong>: Adds a sequential number to each row.</li>



<li><strong>RANK</strong>: Ranks rows and leaves a gap when there are ties (rows values equal).</li>



<li><strong>DENSE_RANK</strong>: Like RANK but doesn’t leave gaps when there are ties.</li>
</ul>



<p>The <a href="https://learn.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-ver16" target="_blank" rel="noreferrer noopener">OVER</a> clause allows you to define your window frame. Additionally, you can tell the frame how many prior rows to include with the <strong>ROWS PRECEDING</strong> argument. Before we build the 7-day average, let’s look at a simple example. Moving average in SQL.</p>



<pre class="wp-block-code"><code>-- simple test
-- mssqltips.com
DECLARE @Simple_Test AS TABLE (Id INT);
INSERT INTO @Simple_Test
(Id) VALUES (1),(2),(3),(4),(5);

SELECT Id,
       SUM(Id) OVER (ORDER BY Id ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS Value
FROM @Simple_Test;
GO</code></pre>



<p>To achieve moving average, use the argument <strong>ROWS BETWEEN 1 PRECEDING AND CURRENT ROW</strong>.</p>



<pre class="wp-block-code"><code>-- mssqltips.com
SET STATISTICS TIME, IO ON;
SELECT t1.UserId,
       t1.DateRecorded,
       t1.Pounds,
       AVG(t1.Pounds) 
         OVER (
           PARTITION BY t1.UserId 
              ORDER BY t1.DateRecorded 
                 ROWS BETWEEN 6 PRECEDING AND CURRENT ROW ) AS &#91;7DayMovingAverage]
FROM dbo.BigWeightTracker t1
ORDER BY t1.UserId,
         t1.DateRecorded;
SET STATISTICS TIME, IO OFF;</code></pre>



<p>Statistics. Moving average in SQL</p>



<pre class="wp-block-code"><code>(438000 rows affected)
Tabela „BigWeightTracker”. Liczba skanowań: 5, odczyty logiczne: 1655,

 SQL Server — czasy wykonywania:
  Czas procesora CPU = 3079 ms; upłynęło czasu = 2382 ms.</code></pre>



<h2 class="wp-block-heading">Key Points of Moving average in SQL</h2>



<ul class="wp-block-list">
<li>Windowing functions are an excellent solution for use cases like moving average, where you might otherwise perform self-joins or correlated subqueries to pull back the results.</li>



<li>Additional arguments use in windowing function&nbsp;<a href="https://learn.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-ver16#rows-or-range" target="_blank" rel="noreferrer noopener">ROWS BETWEEN n PRECEDING AND CURRENT ROW</a>.</li>
</ul>



<h2 class="wp-block-heading">Anomaly Detection for User Sessions and Logins using Moving average in SQL</h2>



<pre class="wp-block-code"><code>-- ===================================================================================
-- Anomaly Detection for User Sessions and Logins
--
-- Purpose: This query identifies days with unusual session or login counts.
-- Method:  It flags a day as an anomaly if its count is more than 2 standard
--          deviations away from the 5-day moving average.
-- ===================================================================================

WITH RunningStats AS (
    -- This CTE calculates a 5-day moving average and standard deviation for session
    -- and logged-in user counts. The window includes the current day and the four previous days.
    SELECT
        &#91;Probe_date],
        &#91;User_internet],
        &#91;User_logged],
        &#91;Sesion_count],
        AVG(CAST(Sesion_count AS FLOAT)) OVER (ORDER BY &#91;Probe_date] ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS moving_avg_session,
        STDEV(Sesion_count) OVER (ORDER BY &#91;Probe_date] ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS moving_std_session,
        AVG(CAST(User_logged AS FLOAT)) OVER (ORDER BY &#91;Probe_date] ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS moving_avg_logged,
        STDEV(User_logged) OVER (ORDER BY &#91;Probe_date] ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) AS moving_std_logged
    FROM
        &#91;DBSession_stat]
    -- Restrict the analysis to the last 30 days for relevance.
    WHERE
        &#91;Probe_date] >= DATEADD(day, -30, GETUTCDATE())
)
-- Final step: Select all calculated stats but only for the days flagged as anomalous.
SELECT
    *
FROM
    RunningStats
-- The WHERE clause applies the "2-sigma" rule to filter for anomalies. A day is
-- returned if either the session count or the logged-in user count is anomalous.
WHERE
    -- Condition for session anomaly
    ABS(Sesion_count - moving_avg_session) > 2 * moving_std_session
    OR
    -- Condition for logged-in user anomaly
    ABS(User_logged - moving_avg_logged) > 2 * moving_std_logged;</code></pre>



<p>Here another approach comparing also weekly pattern.</p>



<pre class="wp-block-code"><code>import pandas as pd

# --- 1. Load and Prepare the Data ---

# Load the data from the uploaded CSV file
df = pd.read_csv('Sesion_stat_last_30_days_an_sessions.xlsx - Arkusz4.csv')

# Convert 'Probe_date' to datetime objects for time-based analysis
df&#91;'Probe_date'] = pd.to_datetime(df&#91;'Probe_date'])

# Set the 'Probe_date' as the index of the DataFrame
df = df.set_index('Probe_date').sort_index()


# --- 2. Feature Engineering: Create Baselines for Comparison ---

# Define the number of data points in a week (7 days * 24 hours * 6 10-minute intervals)
# This is used to look back at the same time last week.
PREVIOUS_WEEK_SHIFT = 7 * 24 * 6

# Calculate the 1-hour running average (6 data points * 10 minutes = 60 minutes)
df&#91;'running_avg'] = df&#91;'Sesion_count'].rolling(window=6, min_periods=1).mean()

# Get the session count from the exact same time one week prior
df&#91;'prev_week_sessions'] = df&#91;'Sesion_count'].shift(PREVIOUS_WEEK_SHIFT)


# --- 3. Anomaly Detection Logic ---

# Define the thresholds for what constitutes an anomaly
# A 50% increase over both the running average and the previous week's value
RELATIVE_THRESHOLD = 1.5
# The session count must also be at least this high to be considered
ABSOLUTE_THRESHOLD = 50

# Apply the anomaly detection conditions
df&#91;'is_anomaly'] = (
    (df&#91;'Sesion_count'] > (df&#91;'running_avg'] * RELATIVE_THRESHOLD)) &amp;
    (df&#91;'Sesion_count'] > (df&#91;'prev_week_sessions'] * RELATIVE_THRESHOLD)) &amp;
    (df&#91;'Sesion_count'] > ABSOLUTE_THRESHOLD)
)


# --- 4. Review the Results ---

# Select only the rows where an anomaly was detected
anomalies = df&#91;df&#91;'is_anomaly']].copy()

# Add columns to show the deviation that triggered the flag
anomalies&#91;'pct_over_avg'] = (anomalies&#91;'Sesion_count'] / anomalies&#91;'running_avg'] - 1) * 100
anomalies&#91;'pct_over_prev_week'] = (anomalies&#91;'Sesion_count'] / anomalies&#91;'prev_week_sessions'] - 1) * 100


print("Anomalies Detected:")
# Display the identified anomalies with context
print(anomalies&#91;&#91;
    'Sesion_count',
    'running_avg',
    'prev_week_sessions',
    'pct_over_avg',
    'pct_over_prev_week'
]].round(1))</code></pre>



<p>Program detected following anomalies</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="832" height="320" src="https://mietwood.com/wp-content/uploads/2025/07/image-19.jpg" alt="Moving average in SQL - anomaly detection" class="wp-image-3218" srcset="https://mietwood.com/wp-content/uploads/2025/07/image-19.jpg 832w, https://mietwood.com/wp-content/uploads/2025/07/image-19-300x115.jpg 300w, https://mietwood.com/wp-content/uploads/2025/07/image-19-768x295.jpg 768w" sizes="auto, (max-width: 832px) 100vw, 832px" /><figcaption class="wp-element-caption">Moving average in SQL &#8211; anomaly detection</figcaption></figure>



<p>Moving average in SQL</p>



<p>Read more <a href="https://mietwood.com/python-for-analysts-most-important-datetime-functions">Python for analysts most important datetime functions</a> </p>
<p>The post <a rel="nofollow" href="https://mietwood.com/moving-average-in-sql">Moving average in SQL</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Advanced Programming in SQL and Python &#8211; the course for business analysts</title>
		<link>https://mietwood.com/advanced-programming-in-sql-and-python</link>
					<comments>https://mietwood.com/advanced-programming-in-sql-and-python#comments</comments>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Tue, 01 Jul 2025 07:45:06 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3144</guid>

					<description><![CDATA[<p>Advanced Programming in SQL and Python &#8211; the course for business analysts &#8211; this course aims to equip students with advanced skills in SQL and Python, focusing on their application in business analytics. Through seven mini analytical case studies, students will gain hands-on experience in solving real-world business problems. Course Structure: Week 1-2: Introduction and...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/advanced-programming-in-sql-and-python">Advanced Programming in SQL and Python &#8211; the course for business analysts</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Advanced Programming in SQL and Python &#8211; the course for business analysts &#8211; this course aims to equip students with advanced skills in SQL and Python, focusing on their application in business analytics. Through seven mini analytical case studies, students will gain hands-on experience in solving real-world business problems.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="249" src="https://mietwood.com/wp-content/uploads/2025/07/image.jpg" alt="python sql trend" class="wp-image-3148" srcset="https://mietwood.com/wp-content/uploads/2025/07/image.jpg 1024w, https://mietwood.com/wp-content/uploads/2025/07/image-300x73.jpg 300w, https://mietwood.com/wp-content/uploads/2025/07/image-768x187.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">python sql trend</figcaption></figure>



<h4 class="wp-block-heading" id="coursestructure"><strong>Course Structure:</strong></h4>



<p><strong>Week 1-2: Introduction and Setup</strong></p>



<ul class="wp-block-list">
<li><strong>Lecture:</strong> Overview of SQL and Python in business analytics.</li>



<li><strong>Lab:</strong> Setting up the environment (SQL databases, Python IDEs).</li>



<li><strong>Project 1:</strong> Data Import and Cleaning
<ul class="wp-block-list">
<li><strong>SQL:</strong> Importing data from various sources, cleaning and preprocessing.</li>



<li><strong>Python:</strong> Using pandas for data cleaning and manipulation.</li>
</ul>
</li>
</ul>



<p><strong>Week 3-4: Data Exploration and Visualization</strong></p>



<ul class="wp-block-list">
<li><strong>Lecture:</strong> Techniques for data exploration and visualization.</li>



<li><strong>Lab:</strong> SQL queries for data exploration, Python libraries for visualization (matplotlib, seaborn).</li>



<li><strong>Project 2:</strong> Exploratory Data Analysis (EDA)
<ul class="wp-block-list">
<li><strong>SQL:</strong> Writing complex queries to explore data.</li>



<li><strong>Python:</strong> Visualizing data trends and patterns.</li>
</ul>
</li>
</ul>



<p><strong>Week 5-6: Statistical Analysis</strong></p>



<ul class="wp-block-list">
<li><strong>Lecture:</strong> Statistical methods for business analytics.</li>



<li><strong>Lab:</strong> SQL functions for statistical analysis, Python libraries (numpy, scipy).</li>



<li><strong>Project 3:</strong> Statistical Analysis of Sales Data
<ul class="wp-block-list">
<li><strong>SQL:</strong> Calculating statistical measures (mean, median, standard deviation).</li>



<li><strong>Python:</strong> Performing hypothesis testing and regression analysis.</li>
</ul>
</li>
</ul>



<p><strong>Week 7-8: Predictive Modeling</strong></p>



<ul class="wp-block-list">
<li><strong>Lecture:</strong> Introduction to predictive modeling techniques.</li>



<li><strong>Lab:</strong> SQL for data preparation, Python for model building (scikit-learn).</li>



<li><strong>Project 4:</strong> Predictive Sales Forecasting
<ul class="wp-block-list">
<li><strong>SQL:</strong> Preparing data for modeling.</li>



<li><strong>Python:</strong> Building and evaluating predictive models.</li>
</ul>
</li>
</ul>



<p><strong>Week 9-10: Time Series Analysis</strong></p>



<ul class="wp-block-list">
<li><strong>Lecture:</strong> Time series analysis and forecasting.</li>



<li><strong>Lab:</strong> SQL for time series data manipulation, Python libraries (statsmodels).</li>



<li><strong>Project 5:</strong> Time Series Forecasting
<ul class="wp-block-list">
<li><strong>SQL:</strong> Extracting and transforming time series data.</li>



<li><strong>Python:</strong> Building time series models and forecasting.</li>
</ul>
</li>
</ul>



<p><strong>Week 11-12: Machine Learning Integration</strong></p>



<ul class="wp-block-list">
<li><strong>Lecture:</strong> Integrating machine learning with SQL databases.</li>



<li><strong>Lab:</strong> SQL for data storage and retrieval, Python for machine learning (TensorFlow, Keras).</li>



<li><strong>Project 6:</strong> Customer Segmentation
<ul class="wp-block-list">
<li><strong>SQL:</strong> Storing and retrieving data for machine learning.</li>



<li><strong>Python:</strong> Building and deploying machine learning models.</li>
</ul>
</li>
</ul>



<p><strong>Week 13-14: Advanced Topics and Final Project</strong></p>



<ul class="wp-block-list">
<li><strong>Lecture:</strong> Advanced topics in SQL and Python (optimization, big data).</li>



<li><strong>Lab:</strong> SQL performance tuning, Python for big data (PySpark).</li>



<li><strong>Project 7:</strong> Comprehensive Business Analytics Project
<ul class="wp-block-list">
<li><strong>SQL:</strong> Optimizing queries for large datasets.</li>



<li><strong>Python:</strong> Analyzing and visualizing large datasets.</li>
</ul>
</li>
</ul>



<h4 class="wp-block-heading" id="assessment"><strong>Assessment:</strong></h4>



<ul class="wp-block-list">
<li><strong>Projects:</strong> Each mini project will be assessed based on accuracy, efficiency, and creativity.</li>



<li><strong>Final Project:</strong> A comprehensive project integrating all learned skills.</li>
</ul>



<h4 class="wp-block-heading" id="resources"><strong>Resources:</strong></h4>



<ul class="wp-block-list">
<li><strong>Books:</strong> &#8220;SQL for Data Analytics&#8221; by Upom Malik, Matt Goldwasser, and Benjamin Johnston; &#8220;Python for Data Analysis&#8221; by Wes McKinney.</li>



<li><strong>Online Tutorials:</strong> SQLZoo, DataCamp, Coursera.</li>
</ul>



<h2 class="wp-block-heading">Advanced Programming in SQL and Python</h2>



<p><a href="https://mietwood.com/advanced-programming-in-data-analysis">Advanced Programming in Data Analysis</a></p>



<p><a href="https://datascience.umcs.pl" target="_blank" rel="noopener">https://datascience.umcs.pl</a></p>



<p></p>
<p>The post <a rel="nofollow" href="https://mietwood.com/advanced-programming-in-sql-and-python">Advanced Programming in SQL and Python &#8211; the course for business analysts</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mietwood.com/advanced-programming-in-sql-and-python/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Database Normal Forms Every Developer Should Know</title>
		<link>https://mietwood.com/database-normal-forms-every-developer-should-know</link>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Sat, 28 Jun 2025 19:34:49 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3134</guid>

					<description><![CDATA[<p>Normalization aims to eliminate redundancy and enforce data integrity by organizing data into logical, dependency-driven forms.</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/database-normal-forms-every-developer-should-know">Database Normal Forms Every Developer Should Know</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Normalization aims to eliminate redundancy and enforce data integrity by organizing data into logical, dependency-driven forms.</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://mietwood.com/wp-content/uploads/2025/06/image-14.jpg" alt="" class="wp-image-3135"/></figure>



<ol class="wp-block-list">
<li>First Normal Form (1NF): Removes repeating groups and ensures atomic values in each column.</li>



<li>Second Normal Form (2NF): Removes partial dependencies by ensuring all non-key columns depend on the full primary key.</li>



<li>Third Normal Form (3NF): Eliminates transitive dependencies, ensuring non-key columns depend only on primary keys.</li>



<li>Boyce-Codd Normal Form (BCNF): Strengthens 3NF by removing anomalies that exist due to overlapping candidate keys. If one column depends on some other column, then that “other column” must be enough to identify each row uniquely.</li>



<li>Fourth Normal Form (4NF): Ensures that a table does not mix multiple independent one-to-many relationships for the same entity.</li>
</ol>
<p>The post <a rel="nofollow" href="https://mietwood.com/database-normal-forms-every-developer-should-know">Database Normal Forms Every Developer Should Know</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How To Set The First Day of Week DATEFIRST</title>
		<link>https://mietwood.com/how-to-set-the-first-day-of-week-datefirst</link>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Sun, 29 Dec 2024 12:21:21 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Business Analytics]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=2760</guid>

					<description><![CDATA[<p>How To Set The First Day of Week DATEFIRST &#8211; SET DATEFIRST = 1 sets the first day of the week to Monday. In SQL Server, the first day of the week can be set to any day from 1 (Monday) to 7 (Sunday). This setting affects the output of date-related functions like DATEPART and...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/how-to-set-the-first-day-of-week-datefirst">How To Set The First Day of Week DATEFIRST</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>How To Set The First Day of Week DATEFIRST &#8211; SET DATEFIRST = 1 sets the first day of the week to Monday. In SQL Server, the first day of the week can be set to any day from 1 (Monday) to 7 (Sunday). This setting affects the output of date-related functions like DATEPART and DATENAME. For example, if DATEFIRST is set to 1 (Monday), DATEPART(dw, &#8216;2024-12-29&#8217;) will return 7, because December 29, 2024, is a Sunday. SET DATEFIRST 1.</p>



<h3 class="wp-block-heading">When to Use <code>SET DATEFIRST</code></h3>



<p><strong>Regional Settings</strong>: Use <code>SET DATEFIRST</code> to match the first day of the week with regional or cultural preferences. For example, in many European countries, Monday is considered the first day of the week.</p>



<ul class="wp-block-list">
<li><strong>Consistent Reporting</strong>: Ensure consistency in date-related calculations and reports, especially when working with international data or users from different regions.</li>



<li><strong>Custom Calculations</strong>: When you need specific calculations that depend on the first day of the week, such as weekly summaries or reports.</li>
</ul>



<h2 class="wp-block-heading">How To Set The First Day of Week DATEFIRST</h2>



<p>Here is the code which generate </p>



<pre class="wp-block-code"><code>-- Declare and initialize variables
DECLARE @i INT = 0;                  -- Loop counter
DECLARE @dt DATE;                   -- Current date in loop
DECLARE @dt_blost DATE;            -- Adjusted date based on weekday
DECLARE @tt TABLE (                -- Table variable to store results
    id INT IDENTITY,              -- Auto-incrementing ID
    dt DATE,                      -- Original date
    wd INT,                       -- Weekday number
    dt_blost DATE                 -- Adjusted date
);
DECLARE @wd INT;                   -- Weekday number

-- Set the first day of the week to Monday (1 = Monday, 7 = Sunday)
SET DATEFIRST 1;

-- Initialize @dt with the current date
SET @dt = GETDATE();

-- Loop 20 times to generate dates and adjusted dates
WHILE @i &lt; 20
BEGIN
    -- Add @i days to the current date
    SET @dt = DATEADD(DAY, @i, @dt);

    -- Get the weekday number of the new date
    SET @wd = DATEPART(WEEKDAY, @dt);

    -- Calculate adjusted date (@dt_blost) based on weekday:
    -- If Monday (1), subtract 3 days
    -- If Tuesday (2), subtract 1 day
    -- Otherwise, add 2 days
    SET @dt_blost = DATEADD(DAY,
        IIF(@wd = 1, -3,
            IIF(@wd = 2, -1, 2)), @dt);

    -- Insert the date, weekday, and adjusted date into the table
    INSERT @tt
    SELECT @dt AS dt, @wd AS wd, @dt_blost;

    -- Increment loop counter
    SET @i += 1;
END

-- Display the results
SELECT * FROM @tt;

-- Additional check: show current UTC date, DATEFIRST setting,
-- weekday number and name for the current UTC date
SET DATEFIRST 1;
SELECT 
    GETUTCDATE() AS &#91;getutcdate],
    @@DATEFIRST AS &#91;DATEFIRST],
    DATEPART(WEEKDAY, GETUTCDATE()) AS &#91;datepart_WEEKDAY],
    DATENAME(WEEKDAY, GETUTCDATE()) AS &#91;datename_WEEKDAY];
</code></pre>



<p>Here’s a code in action</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="561" src="https://mietwood.com/wp-content/uploads/2025/07/image-18.jpg" alt="How To Set The First Day of Week DATEFIRST in sql" class="wp-image-3215" srcset="https://mietwood.com/wp-content/uploads/2025/07/image-18.jpg 1024w, https://mietwood.com/wp-content/uploads/2025/07/image-18-300x164.jpg 300w, https://mietwood.com/wp-content/uploads/2025/07/image-18-768x421.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">How To Set The First Day of Week DATEFIRST</figcaption></figure>



<h3 class="wp-block-heading">Explanation</h3>



<ol class="wp-block-list">
<li><strong>Variable Declarations</strong>: The code declares and initializes several variables to store dates, weekday numbers, and a temporary table to hold the results.</li>



<li><strong>SET DATEFIRST</strong>: This sets the first day of the week to Monday, which affects the output of date-related functions.</li>



<li><strong>Loop</strong>: The loop runs 20 times, incrementing the date by the counter value each time.</li>



<li><strong>Date Adjustments</strong>: Based on the weekday, the code adjusts the date:
<ul class="wp-block-list">
<li>If the date is Sunday (weekday 1), it subtracts 3 days.</li>



<li>If the date is Monday (weekday 2), it subtracts 1 day.</li>



<li>For other weekdays, it adds 2 days.</li>
</ul>
</li>



<li><strong>Insert into Temporary Table</strong>: The current date, weekday number, and adjusted date are inserted into the temporary table.</li>



<li><strong>Select from Temporary Table</strong>: The code selects all records from the temporary table to display the results.</li>



<li><strong>Final Select</strong>: The code selects the current UTC date, the DATEFIRST setting, the weekday number, and the weekday name to show the current settings and date information.</li>
</ol>



<p>This script is useful for generating a series of dates, adjusting them based on specific rules, and storing the results for further analysis. If you have any more questions or need further clarification, feel free to ask!</p>



<p>You can read about date and time most important functions in post <a href="https://mietwood.com/python-for-analysts-most-important-datetime-functions">Python for analysts most important datetime functions</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="sqldateandtimefunctionsforpowerbidatetables">SQL Date and Time Functions for Power BI Date Tables</h2>



<p>When building reports in Power BI, a comprehensive <strong>Date Table</strong> is essential for enabling time-based calculations like YTD, MTD, and custom period comparisons. While Power BI can auto-generate a date table, using <strong>SQL</strong> to create one gives you full control over its structure and logic.</p>



<p>Let’s explore key <strong>SQL Server date and time functions</strong> and how to use them to build a robust date table.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="1generatingadaterange">Generating a Date Range</h2>



<p>To create a date table, you need a continuous range of dates. In SQL Server, you can use a loop or a recursive CTE:</p>



<pre class="wp-block-code"><code>DECLARE @StartDate DATE = '2020-01-01';
DECLARE @EndDate DATE = '2030-12-31';

WITH DateCTE AS (
    SELECT @StartDate AS DateValue
    UNION ALL
    SELECT DATEADD(DAY, 1, DateValue)
    FROM DateCTE
    WHERE DateValue &lt; @EndDate
)
SELECT * INTO DateTable FROM DateCTE
OPTION (MAXRECURSION 32767);
</code></pre>



<p>This creates a table with one row per day between 2020 and 2030.</p>



<p>Alternate code you can find here <a href="https://mietwood.com/recursive-cte-in-sql-server">How Works Recursive CTE in SQL Server?</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="2addingdateattributes">Adding Date Attributes</h2>



<p>Once you have the base dates, enrich them with useful columns:</p>



<pre class="wp-block-code"><code>ALTER TABLE DateTable ADD 
    Year INT,
    Month INT,
    MonthName VARCHAR(20),
    Quarter INT,
    Weekday INT,
    WeekdayName VARCHAR(20);

UPDATE DateTable
SET 
    Year = YEAR(DateValue),
    Month = MONTH(DateValue),
    MonthName = DATENAME(MONTH, DateValue),
    Quarter = DATEPART(QUARTER, DateValue),
    Weekday = DATEPART(WEEKDAY, DateValue),
    WeekdayName = DATENAME(WEEKDAY, DateValue);
</code></pre>



<p>These columns allow for flexible filtering and grouping in Power BI.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="3fiscalcalendarandflags">Fiscal Calendar and Flags</h2>



<p>You can also add fiscal logic and flags:</p>



<pre class="wp-block-code"><code>ALTER TABLE DateTable ADD FiscalYear INT;

UPDATE DateTable
SET FiscalYear = CASE 
    WHEN MONTH(DateValue) &gt;= 7 THEN YEAR(DateValue) + 1
    ELSE YEAR(DateValue)
END;
</code></pre>



<p>Add flags like <code>IsWeekend</code>, <code>IsToday</code>, or <code>IsCurrentMonth</code> to simplify DAX expressions.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading" id="conclusion">Conclusion</h2>



<p>SQL’s date and time functions like <code>DATEADD</code>, <code>DATEPART</code>, <code>DATENAME</code>, and <code>YEAR</code> are powerful tools for building a custom date table. Once created, export it to Power BI or use it as a view for dynamic reporting.</p>



<p>Would you like a ready-to-run SQL script for a complete date table?</p>



<p>Post written with the help of <a class="ek-link" href="https://copilot.microsoft.com/" target="_blank" rel="noopener">https://copilot.microsoft.com/</a></p>



<p></p>
<p>The post <a rel="nofollow" href="https://mietwood.com/how-to-set-the-first-day-of-week-datefirst">How To Set The First Day of Week DATEFIRST</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The PIVOT operator in SQL</title>
		<link>https://mietwood.com/the-pivot-operator-in-sql</link>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Fri, 25 Oct 2024 11:12:53 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=2259</guid>

					<description><![CDATA[<p>The PIVOT operator in SQL Server is an advanced relational operator that helps transforming and reorganizing data in a tabular format, enhancing analytical capabilities. It enables the conversion of unique data from rows into columns, thereby allowing for a more streamlined presentation of aggregated data. This transformation is particularly beneficial in generating cross-tabular reports where...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/the-pivot-operator-in-sql">The PIVOT operator in SQL</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The PIVOT operator in SQL Server is an advanced relational operator that helps transforming and reorganizing data in a tabular format, enhancing analytical capabilities. It enables the conversion of unique data from rows into columns, thereby allowing for a more streamlined presentation of aggregated data. This transformation is particularly beneficial in generating cross-tabular reports where data comparison across distinct categories is essential, simplifying complex reporting requirements in data-driven environments.</p>



<p>Here&#8217;s a simple example of using the `PIVOT` command in SQL Server. Suppose you have a table named `Sales` with the following structure:</p>



<pre class="wp-block-code"><code>| Product | Quarter | SalesAmount |
|---------|---------|-------------|
| A | Q1 | 100 |
| A | Q2 | 150 |
| A | Q3 | 200 |
| A | Q4 | 250 |
| B | Q1 | 120 |
| B | Q2 | 180 |
| B | Q3 | 240 |
| B | Q4 | 300 |</code></pre>



<p>You want to transform this data to show total sales for each product per quarter as columns. Here&#8217;s how you can achieve that using the `PIVOT` command:</p>



<pre class="wp-block-code"><code>SELECT Product, &#91;Q1], &#91;Q2], &#91;Q3], &#91;Q4]
FROM ( SELECT Product, Quarter, SalesAmount FROM Sales ) AS SourceTable
PIVOT ( SUM(SalesAmount) FOR Quarter IN (&#91;Q1], &#91;Q2], &#91;Q3], &#91;Q4]) ) AS PivotTable;</code></pre>



<p>In this query (The PIVOT operator in SQL): </p>



<ul class="wp-block-list">
<li>1. The subquery SourceTable selects the relevant columns from the Sales table.</li>



<li>2. The PIVOT operation specifies that we want to aggregate the SalesAmount using the SUM function, and change the Quarter values (Q1, Q2, Q3, Q4) into columns.</li>



<li>3. The final result shows total sales for each product across the quarters, with the quarter names as column headers.</li>
</ul>



<p>The result will be:</p>



<pre class="wp-block-code"><code>| Product | Q1 | Q2 | Q3 | Q4 |
|---------|-----|-----|-----|-----|
| A | 100 | 150 | 200 | 250 |
| B | 120 | 180 | 240 | 300 |</code></pre>



<p></p>



<p>Employing PIVOT involves specifying an aggregation function and a column source from which values will be extracted. A typical use case requires defining the columns to be pivoted and the aggregation logic, such as SUM or AVG, that will be applied to them. This operation facilitates the summarization of large datasets, aiding in data interpretation by highlighting trends, anomalies, and insights that would otherwise remain obscured in traditional row-oriented datasets. It effectively reduces the cognitive load required to analyze and interpret sprawling data representations. The PIVOT operator in SQL.</p>



<p>In SQL Server, strategic use of PIVOT hinges on a deep understanding of the underlying dataset structure and analytical goals. It&#8217;s essential to carefully design the column selection and aggregation criteria to ensure meaningful data transformations that align with the queries&#8217; analytic objectives. By leveraging PIVOT, database professionals can empower stakeholders to make data-driven decisions with high precision and clarity, capitalizing on SQL Server’s robust capabilities for sophisticated data manipulation and presentation.</p>



<p>Here the real example a lange table of date</p>



<pre class="wp-block-code"><code>   SELECT top 100 
          &#91;CustomerIdEx] as Customer
          ,&#91;Dt_ym]
          ,&#91;ErpValueNet_sum]
      FROM &#91;OnnShop20REC].&#91;onn].&#91;DBCust_stat_baskets]
      where Dt_ym >= '2023-09-01' order by 1</code></pre>



<p>As we can see, all months and corresponding sales for certain customer is presented in rows. </p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="371" height="481" src="https://mietwood.com/wp-content/uploads/2024/10/image.jpg" alt="" class="wp-image-2261" srcset="https://mietwood.com/wp-content/uploads/2024/10/image.jpg 371w, https://mietwood.com/wp-content/uploads/2024/10/image-231x300.jpg 231w" sizes="auto, (max-width: 371px) 100vw, 371px" /></figure>



<h2 class="wp-block-heading">The PIVOT operator in SQL</h2>



<p>If we would like to have months in columns and every customer in rows, then we must apply PIVOT</p>



<pre class="wp-block-code"><code>select 
&#91;CustomerIdEx], 
&#91;2023-09-01],
&#91;2023-10-01],
&#91;2023-11-01],
&#91;2023-12-01],
&#91;2024-01-01],
&#91;2024-02-01],
&#91;2024-03-01],
&#91;2024-04-01],
&#91;2024-05-01],
&#91;2024-06-01],
&#91;2024-07-01],
&#91;2024-08-01],
&#91;2024-09-01],
&#91;2024-10-01] from (
    SELECT top 100 
          &#91;CustomerIdEx] 
          ,&#91;Dt_ym]
          ,&#91;ErpValueNet_sum]
      FROM &#91;OnnShop20REC].&#91;onn].&#91;DBCust_stat_baskets]
      where Dt_ym >= '2023-09-01' order by 1
      ) as p
  pivot
  ( sum(&#91;ErpValueNet_sum])
    for &#91;Dt_ym] in (
            &#91;2023-09-01],
            &#91;2023-10-01],
            &#91;2023-11-01],
            &#91;2023-12-01],
            &#91;2024-01-01],
            &#91;2024-02-01],
            &#91;2024-03-01],
            &#91;2024-04-01],
            &#91;2024-05-01],
            &#91;2024-06-01],
            &#91;2024-07-01],
            &#91;2024-08-01],
            &#91;2024-09-01],
            &#91;2024-10-01]   )
  ) as pvt
  order by pvt.&#91;CustomerIdEx]</code></pre>



<p>You can read more about PIVOT here: <a href="https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver16 " target="_blank" rel="noopener">https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-ver16 </a></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1024" height="271" src="https://mietwood.com/wp-content/uploads/2024/10/image-1.jpg" alt="The PIVOT operator in SQL" class="wp-image-2262" srcset="https://mietwood.com/wp-content/uploads/2024/10/image-1.jpg 1024w, https://mietwood.com/wp-content/uploads/2024/10/image-1-300x79.jpg 300w, https://mietwood.com/wp-content/uploads/2024/10/image-1-768x203.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">The PIVOT operator in SQL &#8211; results</figcaption></figure>



<p>We can also build a dynamic sql for similar operations, The PIVOT operator in SQL.</p>



<pre class="wp-block-code"><code>declare @sql_str as nvarchar(max);
declare @key_column as nvarchar(20);
declare @result_columns as nvarchar(max);
declare @source_data as nvarchar(max);
declare @agg_formula as nvarchar(max);
declare @column_field as nvarchar(20);

set @source_data = N'SELECT &#91;Dt_ym]
          ,&#91;CustomerIdEx]
          ,&#91;ErpValueNet_sum]
      FROM &#91;DBCust_stat_baskets]
      where Dt_ym >= ''2023-09-01'' '

set @key_column = '&#91;CustomerIdEx]';
select @result_columns = string_agg(d.&#91;Dt_ym],',') from (
    select &#91;Dt_ym] FROM &#91;DBCust_stat_baskets] where Dt_ym >= '2023-09-01' group by &#91;Dt_ym] ) as d
set @result_columns = '&#91;' + replace(@result_columns,',','],&#91;') +']'
;

set @agg_formula = N'sum(&#91;ErpValueNet_sum])';
set @column_field = N'&#91;Dt_ym]'

set @sql_str = 'select ' + @key_column + ',';
set @sql_str = @sql_str + @result_columns + ' from (';
set @sql_str = @sql_str + @source_data + ') as p PIVOT ( ' ;
set @sql_str = @sql_str + @agg_formula + ' for ' + @column_field + ' in ( ' + @result_columns + ' )' 
set @sql_str = @sql_str + ' ) as pvt ' 

EXEC sp_executesql @sql_str;

print @sql_str;</code></pre>



<p>In this example, we&#8217;ll write a dynamic SQL (The PIVOT operator in SQL) query to handle scenarios where the pivot columns aren&#8217;t known in advance. Dynamic SQL is particularly useful for creating flexible queries that adapt to varying data structures, such as dynamically-generated columns for a pivot operation. Below is a detailed explanation of a dynamic SQL approach to perform a pivot operation in SQL Server.</p>



<p>Dynamic SQL allows for building queries based on dynamic parameters or outputs from other SQL statements. For example, consider a `Sales` table where the `Quarter` values may vary and need to be dynamically determined for the pivot operation. Initially, you&#8217;ll retrieve distinct `Quarter` values from the `Sales` table into a string of comma-separated values for use as pivot columns. This can be achieved using the `STUFF` and `FOR XML PATH` techniques to concatenate column names.</p>



<pre class="wp-block-code"><code>sql
DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
-- Dynamically create a string of column names
SELECT @columns = STUFF((SELECT DISTINCT ',' + QUOTENAME(Quarter)
FROM Sales
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

-- Construct the dynamic SQL query
SET @sql = N'SELECT Product, ' + @columns + '
FROM (SELECT Product, Quarter, SalesAmount FROM Sales) AS SourceTable
PIVOT (SUM(SalesAmount) FOR Quarter IN (' + @columns + ')) AS PivotTable;';

-- Execute the dynamic SQL query
EXEC sp_executesql @sql;</code></pre>



<p>This code snippet first retrieves unique quarter names dynamically, then builds and executes a pivot query. The PIVOT operator in SQL. It showcases dynamic SQL’s power in handling variable datasets, offering a flexible, adaptable mechanism for data transformation where column values may change over time or differ across environments.</p>



<h2 class="wp-block-heading"> sp_executesql and EXEC</h2>



<p>In SQL Server, both `sp_executesql` and `EXEC` can be used to execute dynamic SQL queries, but they have distinct differences and use cases (The PIVOT operator in SQL):</p>



<h2 class="wp-block-heading">Parameterization</h2>



<p>sp_executesql: This is a system stored procedure that allows for parameterized queries. You can define and pass parameters, making the SQL execution more secure and efficient by helping to prevent SQL injection attacks and promoting better query plan reuse. For instance, you can execute a query with variable inputs by defining parameters like this:</p>



<pre class="wp-block-code"><code>DECLARE @sql NVARCHAR(MAX), @paramDefinition NVARCHAR(MAX);
SET @sql = N'SELECT * FROM Sales WHERE Product = @ProductName';
SET @paramDefinition = N'@ProductName NVARCHAR(50)';
EXEC sp_executesql @sql, @paramDefinition, @ProductName = 'A';</code></pre>



<p>EXEC: This command can execute SQL statements or stored procedures but doesn’t inherently support parameterization. It is commonly used for running stored procedures or executing SQL strings directly. If you use it with dynamic SQL, concatenation of strings may be necessary, which can expose the application to SQL injection risks. The PIVOT operator in SQL.</p>



<h2 class="wp-block-heading">Execution Plan Reuse of sp_executesql and exec</h2>



<ul class="wp-block-list">
<li><strong>sp_executesql</strong>: Supports better execution plan reuse because it maintains parameterized queries. Since the structure of the query remains consistent across executions with only parameter values changing, SQL Server can efficiently reuse cached execution plans, optimizing performance.</li>



<li><strong>EXEC</strong>: When using dynamic SQL with EXEC, frequent changes in concatenated queries can lead to the creation of multiple execution plans, each tailored to specific string values. This reduces execution plan efficiency and increases resource utilization.</li>
</ul>



<h2 class="wp-block-heading">Security and Safety</h2>



<ul class="wp-block-list">
<li><strong>sp_executesql</strong>: Offers more security advantages by allowing parameterization, which reduces the risk of SQL injection. Parameters are explicitly defined and separated from the query logic.</li>



<li><strong>EXEC</strong>: More prone to SQL injection attacks if not used carefully with input validation and escaping since parameters are often included through string concatenation.</li>
</ul>



<p>In summary, sp_executesql is generally preferable for executing dynamic SQL as it provides robust support for parameterized queries, enhancing both security and performance through execution plan reuse. On the other hand, EXEC is simpler but less secure and efficient for complex dynamic SQL scenarios. The PIVOT operator in SQL.</p>



<h2 class="wp-block-heading">The PIVOT operator in SQL</h2>
<p>The post <a rel="nofollow" href="https://mietwood.com/the-pivot-operator-in-sql">The PIVOT operator in SQL</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
