<?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/category/sql/feed" rel="self" type="application/rss+xml" />
	<link>https://mietwood.com</link>
	<description>Customer Experience Can Be Managed</description>
	<lastBuildDate>Wed, 31 Dec 2025 11:44:55 +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>Product Grouping in Noisy E-commerce Datasets</title>
		<link>https://mietwood.com/product-grouping-in-noisy-e-commerce-datasets</link>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Tue, 30 Dec 2025 09:34:33 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3438</guid>

					<description><![CDATA[<p>Hybrid Approaches to Product Grouping in Noisy E-commerce Datasets: A Comparative Analysis of Set-Theoretic vs. Vector Space Models. In scientific literature, this problem is formally known as Short Text Clustering (STC) or Product Entity Resolution. The product similarity measures can be read from here: Measuring product similarity &#8211; 5 important secrets of python programming. Machine...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/product-grouping-in-noisy-e-commerce-datasets">Product Grouping in Noisy E-commerce Datasets</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Hybrid Approaches to Product Grouping in Noisy E-commerce Datasets: A Comparative Analysis of Set-Theoretic vs. Vector Space Models. In scientific literature, this problem is formally known as <strong>Short Text Clustering (STC)</strong> or <strong>Product Entity Resolution</strong>. The product similarity measures can be read from here: <a href="https://mietwood.com/measuring-product-similarity">Measuring product similarity &#8211; 5 important secrets of python programming</a>. Machine learning of product clustering you can find here: <a href="https://mietwood.com/hierarchical-agglomerative-clustering-for-product-grouping">Hierarchical Agglomerative Clustering for Product Grouping</a>.</p>



<h3 class="wp-block-heading">The &#8220;Marketplace Deduplication&#8221; Problem</h3>



<p>Context: Large marketplaces (Amazon, eBay, Alibaba, or a niche aggregator) allow thousands of third-party sellers to upload their own product feeds. Product Grouping for E-commerce Datasets indeed.</p>



<p>The Problem:</p>



<ul class="wp-block-list">
<li>Seller A uploads: <em>&#8220;Apple iPhone 13, 128GB, Midnight&#8221;</em></li>



<li>Seller B uploads: <em>&#8220;iPhone 13 128 GB Black Unlocked&#8221;</em></li>



<li>Seller C uploads: <em>&#8220;Smartfon Apple iPhone 13 128GB (MLPF3PM/A)&#8221;</em></li>
</ul>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Why it&#8217;s hard &#8211; The Scientific Challenge</strong></summary>
<ul class="wp-block-list">
<li><strong>Missing Identifiers:</strong> Sellers often omit EAN/UPC codes to avoid price comparisons.</li>



<li><strong>Attribute Noise:</strong> &#8220;Midnight&#8221; vs. &#8220;Black&#8221; (synonyms).</li>



<li><strong>Goal:</strong> You must cluster these into a <strong>single catalog entry</strong> (The &#8220;Golden Record&#8221;) to show the user one product page with a list of 3 sellers, rather than 3 separate search results.</li>



<li>** Metric:** <em>False Positives</em> are costly here (grouping an iPhone 13 <strong>Pro</strong> with a regular iPhone 13 causes returns).</li>
</ul>
</details>



<h3 class="wp-block-heading">The &#8220;Omnichannel Customer Stitching&#8221; Problem (Single Customer View)</h3>



<p>Context: A retailer sells through a Website, a Mobile App, and Physical Stores. They want to know if the person browsing the app is the same person buying in the store.</p>



<p>The Problem:</p>



<ul class="wp-block-list">
<li><strong>Record A (Online):</strong> <code>email: j.smith@gmail.com</code>, <code>cookie_id: xyz123</code>, <code>behavior: viewed running shoes</code></li>



<li><strong>Record B (In-Store POS):</strong> <code>card_hash: ****-1234</code>, <code>loyalty_id: 998877</code>, <code>name: John Smith</code></li>



<li><strong>Record C (Customer Support):</strong> <code>phone: +48 500...</code>, <code>name: Johnny Smith</code>, <code>complaint: "Shoes size 42 too small"</code></li>
</ul>



<p><strong>Why it&#8217;s hard:</strong></p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Why it&#8217;s hard</strong></summary>
<ul class="wp-block-list">
<li><strong>Disjoint Attributes:</strong> Record A has no phone number; Record C has no email. You need &#8220;transitive linking&#8221; (A links to B, B links to C $\rightarrow$ A links to C).</li>



<li><strong>Privacy/Hashing:</strong> You are often matching hashed values or partial PII (Personally Identifiable Information).</li>



<li><strong>Goal:</strong> Create a <strong>Customer 360</strong> profile to send a targeted email: <em>&#8220;Hi John, sorry the size 42 didn&#8217;t fit. Here is a discount for size 43.&#8221;</em></li>
</ul>
</details>



<h3 class="wp-block-heading">The &#8220;Competitor Price Monitoring&#8221; Problem</h3>



<p>Context: An e-commerce store wants to automatically adjust their prices to be $1 cheaper than their biggest competitor.</p>



<p>The Problem:</p>



<ul class="wp-block-list">
<li><strong>Your Product:</strong> <em>&#8220;Samsung Galaxy S20 FE 5G Cloud Navy&#8221;</em></li>



<li><strong>Competitor Site:</strong> <em>&#8220;Samsung S20 Fan Edition (Navy) &#8211; 5G Compatible&#8221;</em></li>
</ul>



<p><strong>Why it&#8217;s hard:</strong></p>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>Why it&#8217;s hard &#8211; The Scientific Challenge:</strong></summary>
<ul class="wp-block-list">
<li><strong>Adversarial Data:</strong> Competitors intentionally slightly alter names or use unique internal SKUs to prevent scraping and matching.</li>



<li><strong>Asymmetry:</strong> You have your full database (structured), but the competitor data is scraped (unstructured, noisy HTML).</li>



<li><strong>Goal:</strong> Map competitor SKUs to your SKUs with high precision. If you map to the wrong product (e.g., a cheaper &#8220;Lite&#8221; version), your dynamic pricing algorithm will lower your price too much and you lose money.</li>
</ul>
</details>



<h4 class="wp-block-heading"><strong>Abstract</strong></h4>



<ul class="wp-block-list">
<li><strong>Problem:</strong> E-commerce catalogs suffer from redundancy (same product, different sizes/variants).</li>



<li><strong>Gap:</strong> Manual grouping is impossible; Deep Learning is overkill/imprecise for strict SKU grouping.</li>



<li><strong>Method:</strong> We compare Jaccard (Set) vs. TF-IDF (Vector) and propose a normalization pipeline.</li>



<li><strong>Result:</strong> Our method achieved X% accuracy with Y% reduction in computational time.</li>
</ul>



<h4 class="wp-block-heading"><strong>Set-Theoretic Approaches for Product Grouping (Jaccard)</strong></h4>



<ul class="wp-block-list">
<li><strong>Concept:</strong> Treats text as a &#8220;Bag of Words&#8221; (BoW) without weights.</li>



<li><strong>Key Papers/Concepts:</strong>
<ul class="wp-block-list">
<li><em>Cohen et al. (2003)</em> often discuss string metrics for entity matching.</li>



<li><strong>Shingling / MinHash:</strong> In large datasets, calculating Jaccard for all pairs is $O(N^2)$. Literature focuses on <strong>Locality Sensitive Hashing (LSH)</strong> (MinHash) to approximate Jaccard similarity efficiently.</li>



<li><strong>Pros in Literature:</strong> High interpretability, excellent for &#8220;near-duplicate&#8221; detection.</li>



<li><strong>Cons:</strong> Fails when synonyms are used (e.g., &#8220;pants&#8221; vs &#8220;trousers&#8221;) or when word importance varies.</li>
</ul>
</li>
</ul>



<h4 class="wp-block-heading"><strong>Vector Space Models (TF-IDF)</strong></h4>



<ul class="wp-block-list">
<li><strong>Concept:</strong> Maps text to a high-dimensional Euclidean space.</li>



<li><strong>Key Papers/Concepts:</strong>
<ul class="wp-block-list">
<li><em>Salton et al. (1975)</em> (The foundational VSM paper).</li>



<li><strong>Character n-grams:</strong> Papers often cite that for noisy user-generated content (UGC), character n-grams outperform word tokens because they handle misspellings morphologically.</li>



<li><strong>Pros:</strong> Handles &#8220;rare words&#8221; (like model numbers) better due to IDF (Inverse Document Frequency) weighting.</li>
</ul>
</li>
</ul>



<h4 class="wp-block-heading"><strong>The State-of-the-Art (Deep Learning / Embeddings)</strong></h4>



<ul class="wp-block-list">
<li>If you publish, reviewers will ask: <em>&#8220;Why not BERT?&#8221;</em></li>



<li><strong>SBERT (Sentence-BERT):</strong> Current SOTA uses transformer models to generate dense vector embeddings.</li>



<li><strong>Your Counter-Argument:</strong> Deep learning is computationally expensive and &#8220;black-box&#8221;. For industrial product grouping where <em>exact</em> feature matching (like &#8220;Samsung&#8221; + &#8220;Galaxy&#8221;) is critical, classical methods (TF-IDF/Jaccard) often offer better precision and control than semantic embeddings which might group &#8220;iPhone 12&#8221; with &#8220;Samsung S20&#8221; because they are both &#8220;phones&#8221;.</li>
</ul>



<h4 class="wp-block-heading"><strong>II. Related Work</strong></h4>



<ul class="wp-block-list">
<li>Mention <strong>LSH</strong> (Locality Sensitive Hashing) for Jaccard.</li>



<li>Mention <strong>DBSCAN</strong> and <strong>Agglomerative Clustering</strong> as standard algorithms.</li>



<li>Cite limitations of <strong>BERT</strong> in high-precision SKU matching.</li>



<li>Product Grouping for E-commerce</li>
</ul>



<h4 class="wp-block-heading"><strong>III. Methodology (The Core)</strong></h4>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary>Group definition in dataset</summary>
<ul class="wp-block-list">
<li>Define <strong>SKU</strong> vs <strong>Product Group</strong> (Parent-Child relationship).</li>



<li>The challenge: &#8220;Noise&#8221; in titles (e.g., <code>500ml</code>, <code>XL</code>, <code>Pack of 2</code>).</li>
</ul>
</details>



<ol start="1" class="wp-block-list">
<li><strong>Preprocessing &#8211;  The Normalization Filter for Product Grouping for E-commerce:</strong>
<ul class="wp-block-list">
<li>Define your Regex rules mathematically.</li>



<li>$T_{clean} = f(T_{raw})$ where $f$ removes tokens $t \in \{Dimensions, Colors, Stopwords\}$.</li>
</ul>
</li>



<li><strong>Representation:</strong>
<ul class="wp-block-list">
<li><strong>Approach A (Jaccard):</strong> $J(A,B) = \frac{|A \cap B|}{|A \cup B|}$</li>



<li><strong>Approach B (TF-IDF):</strong> Cosine Similarity $\cos(\theta) = \frac{A \cdot B}{||A|| ||B||}$</li>
</ul>
</li>



<li><strong>Clustering Algorithm:</strong>
<ul class="wp-block-list">
<li>Explain why you chose <strong>Connected Components</strong> (Graph theory) for Jaccard or <strong>Hierarchical Clustering</strong> for TF-IDF.</li>
</ul>
</li>
</ol>



<h4 class="wp-block-heading"><strong>IV. Experiments</strong> (Product Grouping for E-commerce)</h4>



<ul class="wp-block-list">
<li><strong>Dataset:</strong> Your dataset of &#8220;several thousand products&#8221;.</li>



<li><strong>Metrics:</strong> You <em>must</em> measure quality.
<ul class="wp-block-list">
<li><strong>Precision:</strong> Are elements in the cluster actually the same product?</li>



<li><strong>Recall:</strong> Did we find <em>all</em> sizes of that product?</li>



<li><strong>F1-Score:</strong> Harmonic mean of the two.</li>
</ul>
</li>
</ul>



<h4 class="wp-block-heading"><strong>V. Results &amp; Discussion</strong></h4>



<ul class="wp-block-list">
<li><em>Hypothesis:</em> Jaccard works better for clean data; TF-IDF works better for noisy data (typos).</li>



<li><em>Observation:</em> Jaccard is faster but TF-IDF + N-grams is more robust.</li>
</ul>



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



<p><strong>Novel Algorithm:</strong></p>



<ol start="1" class="wp-block-list">
<li><strong>Stage 1 (Blocking):</strong> Use <strong>Jaccard</strong> on tokens to quickly find &#8220;Candidate Pairs&#8221; (fast, rough filter).</li>



<li><strong>Stage 2 (Refinement):</strong> Use <strong>TF-IDF with Character N-grams</strong> on the candidates to calculate a precise similarity score (handles typos).</li>



<li><strong>Stage 3 (Decision):</strong> Hard threshold (e.g., >0.85).</li>
</ol>



<h3 class="wp-block-heading">Relevant Search Terms &amp; Papers</h3>



<p>Entity Resolution (ER) is the problem of identifying which records in a database refer to the same real-world entity. An exhaustive ER process involves computing the similarities between pairs of records, which can be very expensive for large datasets. Various blocking techniques can be used to enhance the performance of ER by dividing the records into blocks in multiple ways and only comparing records within the same block. </p>



<p>However, most blocking techniques process blocks separately and do not exploit the results of other blocks. In this paper (<a href="https://dl.acm.org/doi/pdf/10.1145/1559845.1559870" target="_blank" rel="noopener">https://dl.acm.org/doi/pdf/10.1145/1559845.1559870</a>), authors propose an iterative blocking framework where the ER results of blocks are reflected to subsequently processed blocks. Blocks are now iteratively processed until no block contains any more matching records.</p>



<p>Compared to simple blocking, iterative blocking may achieve higher accuracy because reflecting the ER results of blocks to other blocks may generate additional record matches. Iterative blocking may also be more efficient because processing a block now saves the processing time for other blocks.</p>



<ul class="wp-block-list">
<li><strong>&#8220;Short Text Clustering for E-commerce&#8221;</strong></li>



<li><strong>&#8220;Product Entity Resolution with Noise&#8221;</strong></li>



<li><strong>&#8220;Comparison of Jaccard and Cosine Similarity in Text Mining&#8221;</strong></li>



<li><strong>&#8220;Blocking techniques for Entity Resolution&#8221;</strong> (This is crucial for scaling to thousands/millions of products). Product Grouping for E-commerce. </li>
</ul>



<p><strong>Specific types of papers to look for:</strong></p>



<ol start="1" class="wp-block-list">
<li><em>Koporec et al.</em>: Papers on combining Jaccard with other metrics. <a href="https://www.sciencedirect.com/science/article/pii/S1364815225002981" target="_blank" rel="noopener">https://www.sciencedirect.com/science/article/pii/S1364815225002981</a></li>



<li><em>Ganesan et al.</em>: Research on &#8220;abstractive summarization&#8221; or short-text clustering in retail.</li>
</ol>



<h3 class="wp-block-heading"><strong>FAQ: Product Grouping in Noisy E-Commerce Datasets</strong></h3>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>1. What does “noisy data” mean in e-commerce?</strong></summary>
<p>Noisy data refers to inconsistencies, errors, or irrelevant information in product listings—such as misspellings, incomplete descriptions, or duplicate entries—that make grouping products challenging.</p>
</details>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>2. Why is product grouping important?</strong></summary>
<p>Grouping similar products improves search accuracy, recommendation quality, and overall user experience. It also helps businesses manage inventory and pricing strategies more effectively</p>
</details>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>3. What are common challenges in product grouping?</strong></summary>
<ul class="wp-block-list">
<li>Variations in product names and descriptions</li>



<li>Missing or incorrect attributes</li>



<li>Multiple languages or regional differences</li>



<li>Inconsistent categorization by sellers</li>
</ul>
</details>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>4. Which techniques are used to handle noisy datasets?</strong></summary>
<ul class="wp-block-list">
<li><strong>Text normalization</strong> (removing special characters, standardizing case)</li>



<li><strong>Tokenization and similarity measures</strong> (e.g., cosine similarity, Jaccard index)</li>



<li><strong>Machine learning models</strong> for clustering and classification</li>



<li><strong>Attribute-based matching</strong> using structured data</li>
</ul>
</details>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>5. Can AI improve product grouping accuracy?</strong></summary>
<p><br>Yes. AI models like BERT or domain-specific embeddings can capture semantic meaning in product descriptions, making grouping more accurate even with noisy data.</p>
</details>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><strong>6. How do I start implementing product grouping?</strong></summary>
<p><br>Begin with data cleaning and normalization, then apply similarity-based clustering or train a supervised model if labeled data is available.</p>
</details>



<p></p>
<p>The post <a rel="nofollow" href="https://mietwood.com/product-grouping-in-noisy-e-commerce-datasets">Product Grouping in Noisy E-commerce Datasets</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<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>Query optimization with join condition</title>
		<link>https://mietwood.com/query-optimization-with-join-condition</link>
					<comments>https://mietwood.com/query-optimization-with-join-condition#comments</comments>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Mon, 06 Oct 2025 18:04:33 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3349</guid>

					<description><![CDATA[<p>Microsoft SQL Server (MS SQL Server) is a relational database management system (RDBMS) developed by Microsoft. Transact-SQL (T-SQL) is the specific dialect of the SQL (Structured Query Language) that you use to communicate with a Microsoft SQL Server database. The query to be optimized Here there is a query. The table has no index. How...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/query-optimization-with-join-condition">Query optimization with join condition</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Microsoft SQL Server (MS SQL Server) is a <strong>relational database management system</strong> (RDBMS) developed by Microsoft. Transact-SQL (T-SQL) is the <strong>specific dialect of the SQL</strong> (Structured Query Language) that you use to communicate with a Microsoft SQL Server database. </p>



<h2 class="wp-block-heading">The query to be optimized</h2>



<p>Here there is a query. The table has no index. How can we optimize the query and the table reading performance setting up indices? select k.*, </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>select k.*, 
       c.&#91;Top_segment&#93;
      ,c.&#91;CompanyType&#93;
      ,c.&#91;Potencial&#93; from (
    select 
          a.&#91;Dt_ym&#93;
          ,a.&#91;CustomerIdEx&#93;
          ,sum(a.ErpRegisterDoc_count) ErpRegisterDoc_count
          ,sum(a.ErpValueNet_sum) ErpValueNet_sum, sum(b.ErpValueNet_sum) ErpValueNet_sum_py
    FROM &#91;onn&#93;.&#91;DBCust_stat_baskets&#93; a with (nolock)
      left join &#91;onn&#93;.&#91;DBCust_stat_baskets&#93; b with (nolock) 
          on dateadd(year, 1, b.dt_ym) = a.Dt_ym and b.&#91;CustomerIdEx&#93; = a.CustomerIdEx
group by           a.&#91;Dt_ym&#93;
          ,a.&#91;CustomerIdEx&#93;
 ) as k 
  left join &#91;onn&#93;.&#91;DBCust_erp&#93; c with (nolock) on k.CustomerIdEx = c.Cust_nr</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 style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">k</span><span style="color: #ECEFF4">.</span><span style="color: #81A1C1">*</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">       </span><span style="color: #D8DEE9">c</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Top_segment</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9">c</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">CompanyType</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9">c</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Potencial</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #88C0D0">from</span><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: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Dt_ym</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">CustomerIdEx</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #ECEFF4">,</span><span style="color: #88C0D0">sum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ErpRegisterDoc_count</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">ErpRegisterDoc_count</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #ECEFF4">,</span><span style="color: #88C0D0">sum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ErpValueNet_sum</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">ErpValueNet_sum</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sum</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">b</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ErpValueNet_sum</span><span style="color: #D8DEE9FF">) </span><span style="color: #D8DEE9">ErpValueNet_sum_py</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">onn</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">DBCust_stat_baskets</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">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">onn</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">DBCust_stat_baskets</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">b</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">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">on</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">1</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">dt_ym</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Dt_ym</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">and</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">b</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">CustomerIdEx</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">CustomerIdEx</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: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">Dt_ym</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">          </span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9">a</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">CustomerIdEx</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF"> ) </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> k </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">onn</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">DBCust_erp</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">c</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">k</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">CustomerIdEx</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">c</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">Cust_nr</span></span></code></pre></div>



<p>The biggest performance issues here are the <strong>complete lack of indexes</strong> and a <strong>join condition that prevents the use of an index</strong> (even if one existed). You can dramatically speed this up by creating the right indexes and making a small but critical change to the query.</p>



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



<h3 class="wp-block-heading">Setting Up the Right Indices</h3>



<p>An index acts like a book&#8217;s index, allowing SQL Server to find data quickly without scanning the entire table. Based on your query&#8217;s <code>JOIN</code> and <code>GROUP BY</code> clauses, these are the indexes you need.</p>



<h4 class="wp-block-heading">On the <code>DBCust_stat_baskets</code> table:</h4>



<p>This table is joined to itself and grouped by <code>CustomerIdEx</code> and <code>Dt_ym</code>. A <strong>covering index</strong> will be most effective here. This special type of index not only includes the key columns for searching but also the data columns the query needs, allowing the entire subquery to be satisfied from the index alone.</p>



<p>SQL</p>



<pre class="wp-block-code"><code>CREATE NONCLUSTERED INDEX IX_DBCust_stat_baskets_Customer_Date
ON &#91;onn].&#91;DBCust_stat_baskets] (&#91;CustomerIdEx], &#91;Dt_ym])
INCLUDE (&#91;ErpRegisterDoc_count], &#91;ErpValueNet_sum]);
</code></pre>



<ul class="wp-block-list">
<li><strong><code>ON ([CustomerIdEx], [Dt_ym])</code></strong>: This covers your <code>JOIN</code> and <code>GROUP BY</code> columns. The order is important; <code>CustomerIdEx</code> is more selective, so it comes first.</li>



<li><strong><code>INCLUDE (...)</code></strong>: This &#8220;covers&#8221; the <code>SUM</code> calculations, so SQL Server doesn&#8217;t have to look up the data in the main table, which is a massive performance boost.</li>
</ul>



<h4 class="wp-block-heading">On the <code>DBCust_erp</code> table:</h4>



<p>This table is joined on the <code>Cust_nr</code> column. It also needs an index to make the final <code>LEFT JOIN</code> fast.</p>



<p>SQL</p>



<pre class="wp-block-code"><code>CREATE NONCLUSTERED INDEX IX_DBCust_erp_Cust_nr
ON &#91;onn].&#91;DBCust_erp] (&#91;Cust_nr])
INCLUDE (&#91;Top_segment], &#91;CompanyType], &#91;Potencial]);
</code></pre>



<ul class="wp-block-list">
<li><strong><code>ON ([Cust_nr])</code></strong>: Speeds up the join to the subquery <code>k</code>.</li>



<li><strong><code>INCLUDE (...)</code></strong>: Covers the columns you are selecting, again avoiding a second lookup to the main table.</li>
</ul>



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



<h3 class="wp-block-heading">Optimizing the T-SQL Query 🚀</h3>



<p>Your query has a &#8220;non-SARGable&#8221; join condition. SARGable means <strong>S</strong>earch <strong>Arg</strong>ument<strong>able</strong>, allowing SQL to use an index.</p>



<p>The problem is this line: <code>dateadd(year, 1, b.dt_ym) = a.Dt_ym</code>. By applying the <code>dateadd</code> function to the column <code>b.dt_ym</code>, you force SQL Server to calculate a new value for <strong>every single row in the table</strong> before it can perform the join. This guarantees a slow table scan.</p>



<p>The fix is to apply the function to the other side of the equation, so the column itself remains &#8220;clean.&#8221;</p>



<p><strong>Change this:</strong> <code>ON dateadd(year, 1, b.dt_ym) = a.Dt_ym</code></p>



<p><strong>To this:</strong> <code>ON b.dt_ym = dateadd(year, -1, a.Dt_ym)</code></p>



<p>This small change allows SQL Server to take a value from <code>a</code>, calculate the prior year&#8217;s date <em>once</em>, and then perform a highly efficient index seek on <code>b.dt_ym</code> to find the matching row.</p>



<h4 class="wp-block-heading">The Final Optimized Query</h4>



<p>For better readability, I&#8217;ve rewritten your query using a Common Table Expression (CTE). The logic is the same, but it&#8217;s easier to follow. This version incorporates the SARGable join fix.</p>



<p>SQL</p>



<pre class="wp-block-code"><code>-- Use a CTE for better readability to get the current and prior year sums
WITH CustomerMonthlyStats AS (
    SELECT
        a.&#91;Dt_ym],
        a.&#91;CustomerIdEx],
        SUM(a.ErpRegisterDoc_count) AS ErpRegisterDoc_count,
        SUM(a.ErpValueNet_sum) AS ErpValueNet_sum,
        SUM(b.ErpValueNet_sum) AS ErpValueNet_sum_py -- Sum from the previous year
    FROM
        &#91;onn].&#91;DBCust_stat_baskets] AS a
    LEFT JOIN
       &#91;onn].&#91;DBCust_stat_baskets] AS b
        -- OPTIMIZED: The function is now on the outer side of the join, making it SARGable
        ON a.&#91;CustomerIdEx] = b.&#91;CustomerIdEx]
        AND b.dt_ym = DATEADD(year, -1, a.Dt_ym)
    GROUP BY
        a.&#91;Dt_ym],
        a.&#91;CustomerIdEx]
)
-- Final SELECT joining the aggregated stats with customer details
SELECT
    k.*,
    c.&#91;Top_segment],
    c.&#91;CompanyType],
    c.&#91;Potencial]
FROM
    CustomerMonthlyStats AS k
LEFT JOIN
    &#91;onn].&#91;DBCust_erp] AS c ON k.CustomerIdEx = c.Cust_nr;

</code></pre>



<p>By creating these indexes and applying this simple query fix, you should see a dramatic improvement in performance, going from potentially minutes to seconds. I&#8217;d also recommend removing the <code>WITH (NOLOCK)</code> hints after these changes, as they won&#8217;t be necessary and can lead to reading &#8220;dirty&#8221; or incorrect data.</p>



<p><em>You also converted my query to CTE, but I cant use cte in Power BI direct query, that is why I used like that. Do I don&#8217;t know something or CTE is really better then my version of &#8220;cascade&#8221; querying?</em></p>



<p>That&#8217;s an excellent point about Power BI DirectQuery&#8217;s limitations with CTEs. You are correct; you often have to use subqueries (also called derived tables) instead.</p>



<p>To answer your main question: for this specific query, <strong>a CTE is not better than your subquery in terms of performance.</strong> The SQL Server query optimizer is smart enough to see that both your subquery version and the CTE version are logically identical. It will generate the exact same execution plan for both, meaning they will run at the same speed.<sup></sup></p>



<p>The primary advantage of a CTE is <strong>readability and maintainability</strong>, not performance. It helps break down complex logic into clean, sequential steps, making the query easier for a human to understand and debug later.<sup></sup></p>



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



<h3 class="wp-block-heading">The Important Part: The Optimization Itself</h3>



<p>The crucial takeaway from the previous answer was not the switch to a CTE, but these two points:</p>



<ol start="1" class="wp-block-list">
<li><strong>Creating the right indexes</strong> on the tables.</li>



<li><strong>Fixing the non-SARGable join condition</strong>.</li>
</ol>



<p>As long as you apply those two changes, your original query structure is perfectly fine and will be just as fast as the CTE version.</p>



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



<h3 class="wp-block-heading">Your Original Query, Optimized</h3>



<p>Here is your original query with the single, critical change to the <code>JOIN</code> condition. This version avoids CTEs and is ready for Power BI DirectQuery, while still containing the essential performance fix.</p>



<p>SQL</p>



<pre class="wp-block-code"><code>SELECT
    k.*,
    c.&#91;Top_segment],
    c.&#91;CompanyType],
    c.&#91;Potencial]
FROM (
    -- This subquery is functionally the same as the CTE
    SELECT
        a.&#91;Dt_ym],
        a.&#91;CustomerIdEx],
        SUM(a.ErpRegisterDoc_count) AS ErpRegisterDoc_count,
        SUM(a.ErpValueNet_sum) AS ErpValueNet_sum,
        SUM(b.ErpValueNet_sum) AS ErpValueNet_sum_py
    FROM
        &#91;onn].&#91;DBCust_stat_baskets] AS a WITH (NOLOCK)
    LEFT JOIN
        &#91;onn].&#91;DBCust_stat_baskets] AS b WITH (NOLOCK)
        -- The single most important optimization is right here:
        ON a.CustomerIdEx = b.CustomerIdEx AND b.dt_ym = DATEADD(year, -1, a.Dt_ym)
    GROUP BY
        a.&#91;Dt_ym],
        a.&#91;CustomerIdEx]
) AS k
LEFT JOIN
   &#91;onn].&#91;DBCust_erp] AS c WITH (NOLOCK) ON k.CustomerIdEx = c.Cust_nr;

</code></pre>



<p></p>
<p>The post <a rel="nofollow" href="https://mietwood.com/query-optimization-with-join-condition">Query optimization with join condition</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://mietwood.com/query-optimization-with-join-condition/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>Semantic Search</title>
		<link>https://mietwood.com/semantic-search</link>
		
		<dc:creator><![CDATA[Maki Pa]]></dc:creator>
		<pubDate>Wed, 20 Aug 2025 11:33:03 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://mietwood.com/?p=3279</guid>

					<description><![CDATA[<p>Since the advent of ChatGPT in November 2022, there is not a single day goes by without hearing or reading about vector or semantic search. It’s everywhere and so prevalent that we often get the impression this is a new cutting-edge technology. Vector vs lexical search An easy way to introduce vector search is by...</p>
<p>The post <a rel="nofollow" href="https://mietwood.com/semantic-search">Semantic Search</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Since the advent of ChatGPT in November 2022, there is not a single day goes by without hearing or reading about vector or semantic search. It’s everywhere and so prevalent that we often get the impression this is a new cutting-edge technology.</p>



<h2 class="wp-block-heading">Vector vs lexical search</h2>



<p>An easy way to introduce <strong>vector search</strong> is by comparing it to the more conventional <strong>lexical search</strong> that you’re probably used to. <strong>Vector search, also commonly known as semantic search</strong>, and lexical search work very differently. </p>



<p><strong>Lexical search</strong> is the kind of search that we’ve all been using for years. To summarize it very briefly, it doesn’t try to understand the real meaning of what is indexed and queried, instead, it makes a big effort to <strong>lexically</strong> match the literals of the words or variants of them like stemming words, or synonyms, etc.. That makes what the user types in a query with all the literals that have been previously indexed into the database. The similarity is replaced by ranking algorithm, such as TF-IDF.</p>



<p>Documents are tokenized and analyzed. Then, the resulting terms are indexed in an inverted index, which simply maps the analyzed terms to the documents containing them. Searching for “yellow texas roses” will match all documents with varying scores.</p>



<p><strong>Semantic search</strong> &#8211; the whole purpose of semantic search is to index data in such a way that it can be searched based on the meaning it represents.</p>



<h5 class="wp-block-heading">What&#8217;s the difference between semantic search and lexical search?</h5>



<p>Lexical search doesn’t try to understand the real meaning of what is indexed and queried- it matches the literals of the words or their variants. In contrast, vector search indexes data in a way that allows it to be searched based on the meaning it represents.</p>



<p>Read more about vector similarity <a href="https://www.elastic.co/search-labs/blog/introduction-to-vector-search" target="_blank" rel="noopener">https://www.elastic.co/search-labs/blog/introduction-to-vector-search</a></p>



<h2 class="wp-block-heading">Semantic search with elasticsearch</h2>



<p>Load model. See details <a href="https://github.com/elastic/elasticsearch-labs/blob/main/notebooks/search/04-multilingual.ipynb" target="_blank" rel="noopener">here</a> and <a href="https://huggingface.co/intfloat/multilingual-e5-base" target="_blank" rel="noopener">here</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>from elasticsearch import Elasticsearch
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("intfloat/multilingual-e5-base")
VECTOR_DIMENSION = model.get_sentence_embedding_dimension()
print(f"Model loaded successfully.VECTOR_DIMENSION {VECTOR_DIMENSION}")
</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">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">elasticsearch</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Elasticsearch</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">sentence_transformers</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">SentenceTransformer</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">model</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">SentenceTransformer</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">intfloat/multilingual-e5-base</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #8FBCBB">VECTOR_DIMENSION</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">model</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">get_sentence_embedding_dimension</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Model loaded successfully.VECTOR_DIMENSION {VECTOR_DIMENSION}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p>Start elastic server</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>from elasticsearch import Elasticsearch
ES_HOST = "http://localhost:9000"
es = Elasticsearch(hosts=&#91;ES_HOST&#93;)
print(f"Connection successful: {es.info().body&#91;'cluster_name'&#93;}")
</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">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">elasticsearch</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Elasticsearch</span></span>
<span class="line"><span style="color: #8FBCBB">ES_HOST</span><span style="color: #D8DEE9FF"> = </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http://localhost:9000</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #8FBCBB">es</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">Elasticsearch</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">hosts</span><span style="color: #D8DEE9FF">=&#91;</span><span style="color: #8FBCBB">ES_HOST</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Connection successful: {es.info().body&#91;&#39;cluster_name&#39;&#93;}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p>Index product data to elastic database</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># Fetch products from database
def select_products():
    q = """
        SELECT *
        FROM &#91;DB_Products&#93; 
        where &#91;BrandName&#93; in ('PCE','De Walt')
        """
    dfp = read_from_sql_server(q, odbc_conect='DSN=SQLxx')
    return dfp

# >-------------------------------------------------
df_docs = select_products()
print(df_docs.info())
# -------------------------------------------------</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: #D8DEE9FF"># </span><span style="color: #D8DEE9">Fetch</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">products</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">database</span></span>
<span class="line"><span style="color: #D8DEE9">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">select_products</span><span style="color: #D8DEE9FF">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">q</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #A3BE8C">        SELECT </span><span style="color: #D8DEE9">*</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">DB_Products</span><span style="color: #D8DEE9FF">&#93; </span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">where</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #D8DEE9">BrandName</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> (</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">PCE</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">De Walt</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #A3BE8C">    dfp = read_from_sql_server(q, odbc_conect=&#39;DSN=SQLxx&#39;</span><span style="color: #D8DEE9">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">dfp</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #81A1C1">&gt;-------------------------------------------------</span></span>
<span class="line"><span style="color: #D8DEE9">df_docs</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">select_products</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #88C0D0">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">df_docs</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">info</span><span style="color: #D8DEE9FF">())</span></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #81A1C1">-------------------------------------------------</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># Index product names into elastic
index_mapping = {
        "properties": {
            "embedding": {
                "type": "dense_vector",
                "dims":  VECTOR_DIMENSION,
                "index": True,
                "similarity": "cosine"
                },

            "product_name": { 
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256 
                    }
                  }
                },
            "product_name_org": {
                "type": "keyword",
                "ignore_above": 256
                },
            "prodidx": {
                "type": "keyword",
                "ignore_above": 256
                },
            "img_url": {
                "type": "keyword",
                "ignore_above": 512 
                },
            }
        }

# --- 4. Create the Index -------------------------------------------------

INDEX_NAME = 'prod_names_for_search_hybrid'

import time
es.options(ignore_status=&#91;400, 404&#93;).indices.delete(index=INDEX_NAME, ignore_unavailable=True)
time.sleep(3) # Give a moment for index deletion to propagate

if not es.indices.exists(index=INDEX_NAME):
    es.indices.create(index=INDEX_NAME, mappings=index_mapping)
    print("Index created.")
else:
    print("Index already exists.")
# -----------------------------------------------------------------------

# Indexing product data ------------------------------------------------- 
product_names = df_docs&#91;'ProductName'&#93;.apply(lambda x: x.lower()&#91;:256&#93;).to_list()

i = 1
for name in product_names:
    print(f"Indexing:{i} {name}")
    i += 1
    
    vector = model.encode(f"passage: {name}").tolist()
    doc = {
        "Product_name": name,
        "ProductNameVector": vector
    }
    
    es.index(index=INDEX_NAME, document=doc, refresh=True)

# ---------------------------------------------------------------------</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: #D8DEE9FF"># </span><span style="color: #D8DEE9">Index</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">product</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">names</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">into</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">elastic</span></span>
<span class="line"><span style="color: #D8DEE9">index_mapping</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">properties</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">embedding</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">type</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">dense_vector</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">dims</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">VECTOR_DIMENSION</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">index</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">True</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">similarity</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">cosine</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">},</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">product_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">type</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">fields</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                  </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">keyword</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">type</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">keyword</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ignore_above</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">256</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: #D8DEE9FF">                  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">product_name_org</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">type</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">keyword</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ignore_above</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">256</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">prodidx</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">type</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">keyword</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ignore_above</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">256</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">img_url</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">type</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">keyword</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ignore_above</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">512</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: #D8DEE9FF">            </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #81A1C1">---</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4.</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Create</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">the</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Index</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-------------------------------------------------</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">INDEX_NAME</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">prod_names_for_search_hybrid</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">time</span></span>
<span class="line"><span style="color: #8FBCBB">es</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">options</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">ignore_status</span><span style="color: #D8DEE9FF">=&#91;400</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> 404&#93;).</span><span style="color: #8FBCBB">indices</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">delete</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">index</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">INDEX_NAME</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">ignore_unavailable</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">True</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #8FBCBB">time</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">sleep</span><span style="color: #D8DEE9FF">(3) # </span><span style="color: #8FBCBB">Give</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">a</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">moment</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">index</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">deletion</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">to</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">propagate</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">not</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">es</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">indices</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">exists</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">index</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">INDEX_NAME</span><span style="color: #D8DEE9FF">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">es</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">indices</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">create</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">index</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">INDEX_NAME</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">mappings</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">index_mapping</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Index created.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #8FBCBB">else</span><span style="color: #D8DEE9FF">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Index already exists.</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF"># -----------------------------------------------------------------------</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #8FBCBB">Indexing</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">product</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">data</span><span style="color: #D8DEE9FF"> ------------------------------------------------- </span></span>
<span class="line"><span style="color: #8FBCBB">product_names</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">df_docs</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">ProductName</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93;.</span><span style="color: #8FBCBB">apply</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">lambda</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">x</span><span style="color: #D8DEE9FF">: </span><span style="color: #8FBCBB">x</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">lower</span><span style="color: #D8DEE9FF">()&#91;:256&#93;).</span><span style="color: #8FBCBB">to_list</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">i</span><span style="color: #D8DEE9FF"> = 1</span></span>
<span class="line"><span style="color: #8FBCBB">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">product_names</span><span style="color: #D8DEE9FF">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Indexing:{i} {name}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">i</span><span style="color: #D8DEE9FF"> += 1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">vector</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">model</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">encode</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">passage: {name}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">).</span><span style="color: #8FBCBB">tolist</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">doc</span><span style="color: #D8DEE9FF"> = </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">        &quot;</span><span style="color: #8FBCBB">Product_name</span><span style="color: #D8DEE9FF">&quot;: </span><span style="color: #8FBCBB">name</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        &quot;</span><span style="color: #8FBCBB">ProductNameVector</span><span style="color: #D8DEE9FF">&quot;: </span><span style="color: #8FBCBB">vector</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">es</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">index</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">index</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">INDEX_NAME</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">document</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">doc</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">refresh</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">True</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># ---------------------------------------------------------------------</span></span></code></pre></div>



<p>You can check your index using diagnostic functions. Semantic search.</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># --- Diagnostic functions  ---------------------------------------
def indices_list():
    return [index&#91;'index'&#93; for index in es.cat.indices(format='json')]   

def count_records(index_name):
    return es.count(index=index_name)&#91;'count'&#93;    
# -----------------------------------------------------------------

# Get indices and record count ------------------------------------
for i in indices_list():
    print(i, count_records(i))

# Get mapings
mapping = es.indices.get_mapping(index=INDEX_NAME)
fields = mapping&#91;INDEX_NAME&#93;&#91;'mappings'&#93;&#91;'properties'&#93;
for field, details in fields.items():
    print(f"Model {INDEX_NAME}, fields {field}: {details&#91;'type'&#93;}")
#------------------------------------------------------------------</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: #D8DEE9FF"># </span><span style="color: #81A1C1">---</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Diagnostic</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">functions</span><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">---------------------------------------</span></span>
<span class="line"><span style="color: #D8DEE9">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">indices_list</span><span style="color: #D8DEE9FF">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> [</span><span style="color: #D8DEE9">index</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">index</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">index</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">es</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">cat</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">indices</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">format</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">json</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">)]   </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">count_records</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">index_name</span><span style="color: #D8DEE9FF">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">es</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">count</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">index</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">index_name</span><span style="color: #D8DEE9FF">)&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">count</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93;    </span></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #81A1C1">-----------------------------------------------------------------</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">indices</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">and</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">record</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">count</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">------------------------------------</span></span>
<span class="line"><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">indices_list</span><span style="color: #D8DEE9FF">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">i</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">count_records</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">i</span><span style="color: #D8DEE9FF">))</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF"># </span><span style="color: #D8DEE9">Get</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mapings</span></span>
<span class="line"><span style="color: #D8DEE9">mapping</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">es</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">indices</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get_mapping</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">index</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">INDEX_NAME</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9">fields</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mapping</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #D8DEE9">INDEX_NAME</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">mappings</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">properties</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">field</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">details</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fields</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">items</span><span style="color: #D8DEE9FF">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Model {INDEX_NAME}, fields {field}: {details&#91;&#39;type&#39;&#93;}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">#</span><span style="color: #81A1C1">------------------------------------------------------------------</span></span></code></pre></div>



<h2 class="wp-block-heading">Semantic search</h2>



<p>Now when you have index you can search. You can read more in my post <a href="https://mietwood.com/semantic-search-with-elasticsearch">Semantic Search with Elasticsearch</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># Semantic Search --- 

query_text = "yellow texas rose"
query_vector = model.encode(f"query: {query_text}").tolist()
knn_query = {
    "field": "embedding", #"ProductNameVector",
    "query_vector": query_vector,
    "k": 10,
    "num_candidates": 50
}
response = es.search(index=INDEX_NAME, knn=knn_query, source=&#91;"product_name"&#93;)
for hit in response&#91;'hits'&#93;&#91;'hits'&#93;:
    print(f"  - Product: {hit&#91;'_source'&#93;&#91;'product_name'&#93;} (Score: {hit&#91;'_score'&#93;:.4f})")
</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: #D8DEE9FF"># </span><span style="color: #D8DEE9">Semantic</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Search</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">---</span><span style="color: #D8DEE9FF"> </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">query_text</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">yellow texas rose</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9">query_vector</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">model</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">encode</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">query: {query_text}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">tolist</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9">knn_query</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">field</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">embedding</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> #</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ProductNameVector</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">query_vector</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">query_vector</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">k</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">10</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">num_candidates</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">50</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9">response</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">es</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">search</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">index</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">INDEX_NAME</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">knn</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">knn_query</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">source</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">product_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hit</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">response</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">hits</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">hits</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93;:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">print</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">  - Product: {hit&#91;&#39;_source&#39;&#93;&#91;&#39;product_name&#39;&#93;} (Score: {hit&#91;&#39;_score&#39;&#93;:.4f})</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span></code></pre></div>



<p>You can perform also lexical search or finnali hybrid search.</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>def search_score_script(query_h):
    response = es.search(
        index=INDEX_NAME,
        body={
            "_source": &#91;'product_name','prodidx','img_url'&#93;,
            "query": {
                "function_score": {
                    "query": {
                        "bool": {
                            "should": &#91;
                                {
                                    "match": {
                                        "product_name": {
                                            "query": query_h,
                                            'operator': 'and',
                                            "_name": "text_match"
                                        }
                                    }
                                },
                                {
                                    "knn": {
                                        "field": "embedding",
                                        "query_vector": model.encode(f"query: {query_text}").tolist(),
                                        "k": 30,
                                        "num_candidates": 300,
                                        "_name": "semantic_search"
                                    }
                                }
                            &#93;
                        }
                    },                 
                }
            },
            "size": 100
        }
    )
    return response

response = search_score_script(query_h)   
products = [
         {
             "product_name": hit&#91;"_source"&#93;&#91;"product_name"&#93;,
             "score": hit&#91;"_score"&#93;,
             "matched_queries": hit.get("matched_queries", []),
             "prodidx": hit&#91;"_source"&#93;&#91;"prodidx"&#93;,
         }
         for hit in response&#91;"hits"&#93;&#91;"hits"&#93;
     ]

print([(p&#91;"product_name"&#93;,p&#91;"score"&#93; for p in products])
 </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">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">search_score_script</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">query_h</span><span style="color: #D8DEE9FF">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">response</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">es</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">search</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">index</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9">INDEX_NAME</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #D8DEE9">body</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">_source</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> &#91;</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">product_name</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">prodidx</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">img_url</span><span style="color: #ECEFF4">&#39;</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">query</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">function_score</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">query</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">bool</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">should</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> &#91;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">match</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">product_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">query</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">query_h</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                            </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">operator</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">and</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text_match</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">knn</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">field</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">embedding</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">query_vector</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">model</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">encode</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">query: {query_text}</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">tolist</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">k</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">30</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">num_candidates</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">300</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">semantic_search</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                                </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                            &#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">                        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #ECEFF4">},</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: #D8DEE9FF">            </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">size</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">100</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    )</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">response</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9">response</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">search_score_script</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">query_h</span><span style="color: #D8DEE9FF">)   </span></span>
<span class="line"><span style="color: #D8DEE9">products</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</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: #D8DEE9FF">             </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">product_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hit</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">_source</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">product_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">             </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">score</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hit</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">_score</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">             </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">matched_queries</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hit</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">matched_queries</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> [])</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">             </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">prodidx</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hit</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">_source</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">prodidx</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">         </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">         </span><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">hit</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">response</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">hits</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">hits</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">     ]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">print</span><span style="color: #D8DEE9FF">([(</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">product_name</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">score</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93; </span><span style="color: #D8DEE9">for</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">p</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">products</span><span style="color: #D8DEE9FF">])</span></span>
<span class="line"><span style="color: #D8DEE9FF"> </span></span></code></pre></div>



<h4 class="wp-block-heading"><strong>Sentence Transformers (e.g., MiniLM, BERT variants)</strong> are the best choice models for semantic search</h4>



<ul class="wp-block-list">
<li><strong>Type</strong>: Dense vector models.</li>



<li><strong>Pros</strong>:
<ul class="wp-block-list">
<li>Rich semantic understanding.</li>



<li>Multilingual support.</li>



<li>Fine-tuning possible for domain-specific needs.</li>
</ul>
</li>



<li><strong>Popular Models</strong>:
<ul class="wp-block-list">
<li><code>msmarco-MiniLM-L-12-v3</code> – optimized for asymmetric search (short queries vs. long product descriptions) <a>3</a>.</li>



<li><code>all-MiniLM-L6-v2</code> – fast and lightweight for general semantic tasks.</li>
</ul>
</li>



<li><strong>Use Case</strong>: Ideal for large-scale product catalogs and multilingual e-commerce platforms <a>3</a> <a>4</a>.</li>
</ul>



<h4 class="wp-block-heading">3.&nbsp;<strong>Hybrid Search (BM25 + Semantic)</strong></h4>



<ul class="wp-block-list">
<li>Combine <strong>BM25</strong> (keyword relevance) with <strong>semantic embeddings</strong> using <strong>Reciprocal Rank Fusion (RRF)</strong>.</li>



<li>Delivers highly relevant results by balancing literal matches and contextual meaning <a>1</a>.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>
<p>The post <a rel="nofollow" href="https://mietwood.com/semantic-search">Semantic Search</a> appeared first on <a rel="nofollow" href="https://mietwood.com">Customer Experience Management</a>.</p>
]]></content:encoded>
					
		
		
			</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>
	</channel>
</rss>
