{"id":108897,"date":"2026-04-06T13:30:00","date_gmt":"2026-04-06T13:30:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=108897"},"modified":"2026-02-27T11:55:49","modified_gmt":"2026-02-27T11:55:49","slug":"syntax-and-data-structures-in-esproc-spl-a-complete-guide","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/syntax-and-data-structures-in-esproc-spl-a-complete-guide\/","title":{"rendered":"Syntax and data structures in esProc SPL &#8211; a complete guide"},"content":{"rendered":"\n<p><strong>In the previous article of this <a href=\"https:\/\/www.red-gate.com\/simple-talk\/collections\/moving-from-python-to-esproc-spl\/\">&#8220;Moving from Python to esProc SPL&#8221;<\/a> series, I covered how to set up esProc SPL and load your first datasets. It&#8217;s now time to learn what makes esProc SPL a tool for data analysis: its syntax and data structures. In this article, you&#8217;ll learn about SPL&#8217;s core syntax elements, its primary data structure (the table), and how to perform common data operations. By the end, you&#8217;ll understand how to write effective SPL code and how it compares to equivalent operations in Python.<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/www.esproc.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">esProc SPL (Structured Process Language)<\/a> was designed specifically for data processing, with a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Syntax\" target=\"_blank\" rel=\"noreferrer noopener\">syntax<\/a> that prioritizes readability and efficiency for data operations. If you&#8217;re coming from <a href=\"https:\/\/www.python.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Python<\/a>, particularly if you&#8217;ve used <a href=\"https:\/\/pandas.pydata.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Pandas<\/a> for data analysis, you&#8217;ll find some familiar concepts in SPL and discover approaches that can simplify complex data tasks.<\/p>\n\n\n\n<p>In this article, you&#8217;ll learn about SPL&#8217;s core syntax elements, its primary data structure (the table), and how to perform common data operations. By the end, you&#8217;ll understand how to write effective SPL code and how it compares to equivalent operations in <a href=\"https:\/\/www.red-gate.com\/simple-talk\/development\/python\/python-is-good-but-not-perfect-here-are-10-reasons-to-avoid-it\/\" target=\"_blank\" rel=\"noreferrer noopener\">Python<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-esproc-spl-s-syntax-and-how-does-it-compare-to-python\">What is esProc SPL&#8217;s syntax, and how does it compare to Python?<\/h2>\n\n\n\n<p>esProc SPL&#8217;s syntax has a logical flow that will feel familiar if you&#8217;re coming from Python, but with some key differences that make it particularly well-suited for data analysis. Let&#8217;s look at the basic syntax elements and how they compare to Python.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-what-is-esproc-spl-s-basic-syntax\">What is esProc SPL&#8217;s basic syntax?<\/h3>\n\n\n\n<p>SPL introduces a cell-based structure that enhances readability and debugging. It makes SPL useful for complex data operations, where it is essential to track transformations at each step. SPL organizes code into cells, similar to how a spreadsheet works. Each line of code is assigned to a specific cell (A1, B2, C3, etc.), making it easier to follow the flow of calculations.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>= 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Assign the value 10 to cell A1<\/td><\/tr><tr><td>2<\/td><td>= 20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Assign the value 20 to cell A2<\/td><\/tr><tr><td>3<\/td><td>= A1 + A2<\/td><td>Add the values in A1 and A2, store the result in A3<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>When you run this code in the esProc IDE, you&#8217;ll see:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"975\" height=\"206\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-64.png\" alt=\"An image showing what you see when running the code in the esProc SPL IDE.\" class=\"wp-image-108898\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-64.png 975w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-64-300x63.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-64-768x162.png 768w\" sizes=\"auto, (max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p>This cell-based approach creates a visual flow of your data processing steps. Each cell can be inspected individually. In Python, the equivalent would be:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">a1 = 10\na2 = 20\na3 = a1 + a2\nprint(a3)  # Output: 30<\/pre><\/div>\n\n\n\n<p>Python uses a linear, <a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/scripting-out-several-databases-on-a-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">script-based<\/a> approach, meaning you have to run the entire script to see the results. Unlike SPL\u2019s cell-based execution, Python doesn\u2019t inherently allow you to view intermediate outputs unless you manually print them. SPL supports interactive processing; if you modify and rerun a single cell\u2019s value, only the dependent cells need to be executed again, saving time and computational resources.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-what-is-esproc-spl-s-expression-syntax\">What is esProc SPL&#8217;s expression syntax?<\/h3>\n\n\n\n<p>SPL expressions follow a familiar syntax if you&#8217;re coming from Python. You can perform <a href=\"https:\/\/www.w3schools.com\/python\/python_operators_arithmetic.asp\" target=\"_blank\" rel=\"noreferrer noopener\">arithmetic operations<\/a>, <a href=\"https:\/\/www.w3schools.com\/python\/python_strings_concatenate.asp\" target=\"_blank\" rel=\"noreferrer noopener\">string concatenation<\/a>, and logical comparisons just like in Python.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>=5+3*2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Result: 11<\/td><\/tr><tr><td>2<\/td><td>=&#8221;Hello&#8221;+&#8221; World&#8221;&nbsp;<\/td><td>Result: &#8220;Hello World&#8221; &nbsp;<\/td><\/tr><tr><td>3<\/td><td>=A1&gt;10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Result: true<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>When you run this code in the esProc <a href=\"https:\/\/www.codecademy.com\/article\/what-is-ide\" target=\"_blank\" rel=\"noreferrer noopener\">IDE (integrated development environment)<\/a>, you&#8217;ll see:<\/p>\n\n\n\n<p>A1: 11<\/p>\n\n\n\n<p>A2: Hello World<\/p>\n\n\n\n<p>A3: true<\/p>\n\n\n\n<p>The IDE shows both the expression and its evaluated result, making it easy to understand what&#8217;s happening at each step. This is helpful when debugging complex expressions. Python&#8217;s equivalents are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \"># Arithmetic operation: Multiplication happens first, then addition\na1 = 5 + (3 * 2)  # Result: 11\n\n# String concatenation: Combines \"Hello\" and \" World\"\na2 = \"Hello\" + \" World\"  # Result: \"Hello World\"\n\n# Boolean comparison: Checks if a1 is greater than 10\na3 = a1 &gt; 10  # Result: True\n\n# Print the results\nprint(a1, a2, a3)<\/pre><\/div>\n\n\n\n<p>The main difference is that Python uses `True`\/`False` (capitalized) for <a href=\"https:\/\/www.red-gate.com\/simple-talk\/blogs\/setting-boolean-values-in-a-sharepoint-spitemeventreceiver\/\" target=\"_blank\" rel=\"noreferrer noopener\">boolean values<\/a>, while SPL uses `true`\/`false` (lowercase). Also, in Python, you typically need to add print statements to see intermediate results, whereas in SPL, the results are automatically displayed in the IDE.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-does-method-chaining-work-in-esproc-spl\">How does method chaining work in esProc SPL?<\/h3>\n\n\n\n<p>Like Python, SPL supports method chaining, allowing you to perform multiple operations in sequence:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>= file(&#8220;sales.csv&#8221;).import@ct()&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Import CSV file<\/td><\/tr><tr><td>2<\/td><td>= A1.select(Amount&gt;1000)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .sort(Amount:-1) .to(5)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get top 5 rows<\/td><td>Filter rows Sort by Amount descending Get top 5 rows<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output will show the top 5 orders with amounts greater than $1000, sorted by amount in descending order. The table format makes it easy to see each record&#8217;s OrderID, Customer, Product, Amount, and Date. The Python equivalent, using pandas, would be:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd\n\ndf = pd.read_csv(\"sales.csv\")\nresult = df[df['Amount'] &gt; 1000].sort_values('Amount', ascending=False).head(5)\nprint(result)\n<\/pre><\/div>\n\n\n\n<p>Both SPL and pandas accomplish the same task, but SPL\u2019s syntax is more streamlined. Instead of calling multiple functions separately, SPL allows you to chain them in a way that naturally follows how you think about the data: filter, sort, and retrieve.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-comments-and-code-organization-in-esproc-spl\">Comments and code organization in esProc SPL<\/h3>\n\n\n\n<p>In SPL, comments should generally be placed in a separate cell, not mixed with code.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>= 5 * 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Calculate product of 5 and 10<\/td><\/tr><tr><td>2<\/td><td>= A1 \/ 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Divide the result by 2<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This differs from Python&#8217;s `#` comment syntax. SPL also uses indentation to show logical structure in control flows, similar to Python:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><\/tr><tr><td>1<\/td><td>= 15<\/td><\/tr><tr><td>2<\/td><td>= if(A1 &gt; 10, A1*2, A1\/2)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>If written as an \u2018if\u2019 statement, the table should look like this: [if and else are keywords with no preceding = sign]<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>A<\/td><td>B<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>= 15<\/td><td>&nbsp;<\/td><td>&nbsp;<\/td><\/tr><tr><td>2<\/td><td>if A1 &gt; 10<\/td><td>&gt;A1=A1 * 2<\/td><td>Double the value if A1 &gt; 10<\/td><\/tr><tr><td>3<\/td><td>else<\/td><td>&gt;A1=A1 \/ 2<\/td><td>Halve the value if A1 &lt;= 10<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output (A6) would be: 30. Since A1 (15) is greater than 10, the value is doubled to 30.<\/p>\n\n\n\n<section id=\"my-first-block-block_7a2ab8107d32a99c46710f04d0faaaa4\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Simple Talk is brought to you by Redgate Software<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            Take control of your databases with the trusted Database DevOps solutions provider. Automate with confidence, scale securely, and unlock growth through AI.                                    <\/div>\n            <\/div>\n                            <a href=\"https:\/\/www.red-gate.com\/solutions\/overview\/\" class=\"btn btn--secondary btn--lg\">Discover how Redgate can help you<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-do-variables-and-data-types-work-in-esproc-spl\">How do variables and data types work in esProc SPL?<\/h2>\n\n\n\n<p>esProc SPL, like Python, is <a href=\"https:\/\/www.baeldung.com\/cs\/statically-vs-dynamically-typed-languages\" target=\"_blank\" rel=\"noreferrer noopener\">dynamically typed<\/a>, meaning you don&#8217;t need to declare variable types explicitly. However, understanding the available data types is important for effective data manipulation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-what-basic-data-types-are-supported-in-esproc-spl\">What basic data types are supported in esProc SPL?<\/h3>\n\n\n\n<p>SPL supports several basic data types:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><\/tr><tr><td>&nbsp;1<\/td><td>=5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Integer<\/td><\/tr><tr><td>&nbsp;2<\/td><td>=5.25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Decimal<\/td><\/tr><tr><td>&nbsp;3<\/td><td>=&#8221;Hello&#8221;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String<\/td><\/tr><tr><td>&nbsp;4<\/td><td>=true&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean<\/td><\/tr><tr><td>&nbsp;5<\/td><td>=null&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Null value<\/td><\/tr><tr><td>&nbsp;6<\/td><td>=date(&#8220;2023-06-15&#8221;)&nbsp;&nbsp;&nbsp; Date<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>When you run this code in the esProc IDE, you&#8217;ll see:<\/p>\n\n\n\n<p>A1: 5<\/p>\n\n\n\n<p>A2: 5.25<\/p>\n\n\n\n<p>A3: Hello<\/p>\n\n\n\n<p>A4: true<\/p>\n\n\n\n<p>A5: null<\/p>\n\n\n\n<p>A6: 2023-06-15<\/p>\n\n\n\n<p>Each cell shows both the assigned value and its data type through visual cues in the IDE. For example, strings are displayed in a different color than numbers, making it easy to identify the type of each value. Strings are left-aligned, underlined, and displayed in black. Numeric values are right-aligned, with integers in blue and doubles in brown. The Python equivalents are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">a1 = 5              # Integer\na2 = 5.25           # Float\na3 = \"Hello\"        # String\na4 = True           # Boolean\na5 = None           # None value\na6 = datetime.date(2023, 6, 15)  # Date (requires datetime module)\n<\/pre><\/div>\n\n\n\n<p>One key difference is that SPL has built-in support for date values, while <a href=\"https:\/\/docs.python.org\/3\/library\/datetime.html\" target=\"_blank\" rel=\"noreferrer noopener\">Python requires the datetime module<\/a>. This makes working with dates more straightforward in SPL, especially for data analysis tasks that often involve date-based calculations.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-does-type-conversion-work-in-esproc-spl\">How does type conversion work in esProc SPL?<\/h3>\n\n\n\n<p>SPL provides functions for type conversion:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>A<\/td><\/tr><tr><td>&nbsp;1<\/td><td>=&#8221;123&#8243;<\/td><\/tr><tr><td>&nbsp;2<\/td><td>=int(A1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Convert string to integer: 123<\/td><\/tr><tr><td>&nbsp;3<\/td><td>=string(A2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Convert integer to string: &#8220;123&#8221;<\/td><\/tr><tr><td>&nbsp;4<\/td><td>=decimal(&#8220;45.67&#8221;)&nbsp; Convert string to decimal: 45.67<\/td><\/tr><tr><td>&nbsp;5<\/td><td>date(&#8220;2023-06-15&#8221;)&nbsp;&nbsp; Convert string to date: 2023-06-15<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>When you run this code, you&#8217;ll see:<\/p>\n\n\n\n<p>A1: 123 (displayed as a string), A2: 123 (displayed as an integer), A3: 123 (displayed as a string), A4: 45.67 (displayed as a decimal), A5: 2023-06-15 (displayed as a date). The IDE helps you distinguish between different types through visual cues, even when the displayed value looks the same (like the string &#8220;123&#8221; and the integer 123).<\/p>\n\n\n\n<p>Python&#8217;s equivalents are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import datetime\n\n# Define a string containing numeric characters\na1 = \"123\"\n\n# Convert string to integer\na2 = int(a1)  # Result: 123\n\n# Convert integer back to string\na3 = str(a2)  # Result: \"123\"\n\n# Convert string to floating-point number\na4 = float(\"45.67\")  # Result: 45.67\n\n# Convert string to date\na5 = datetime.datetime.strptime(\"2023-06-15\", \"%Y-%m-%d\").date()  # Result: 2023-06-15\n\n# Print results\nprint(a2, type(a2))  # Output: 123 &lt;class 'int'&gt;\nprint(a3, type(a3))  # Output: 123 &lt;class 'str'&gt;\nprint(a4, type(a4))  # Output: 45.67 &lt;class 'float'&gt;\nprint(a5, type(a5))  # Output: 2023-06-15 &lt;class 'datetime.date'&gt;<\/pre><\/div>\n\n\n\n<p>Notice how date conversion in Python requires more code and knowledge of format strings, while SPL&#8217;s date function is more straightforward for common date formats.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-comparing-esproc-spl-s-primary-data-structure-the-table-sequence-to-python-s-dataframe\">Comparing esProc SPL&#8217;s primary data structure &#8211; the table sequence &#8211; to Python&#8217;s DataFrame<\/h2>\n\n\n\n<p>The table sequence is SPL&#8217;s primary data structure for handling tabular data, similar to Python&#8217;s DataFrame in pandas. However, there are important differences in how they work and are manipulated.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-create-a-table-sequence-in-esproc-spl\">How do you create a table sequence in esProc SPL?<\/h3>\n\n\n\n<p>Let&#8217;s create a table sequence by importing a CSV file:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>A<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()&nbsp;&nbsp;&nbsp;<\/td><td>Sales data with 100 rows<\/td><\/tr><tr><td>2<\/td><td>=A1.to(5)<\/td><td>First 5 rows of the table<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The order of @t and @c does not matter, meaning @ct and @tc are equivalent. If neither the option nor the parameter specifies a delimiter, the default is tab-separated.<\/p>\n\n\n\n<p>If you need to preserve leading zeros or other special formatting, you can use `import@f` to import data as raw strings without parsing:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/zip_codes.csv&#8221;).import@ctf()&nbsp;&nbsp;&nbsp;<\/td><td>ZIP code data with leading zeros preserved<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The Python equivalent is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd\n\n# Import CSV as DataFrame\nsales_df = pd.read_csv(\"sales.csv\")\n# View first 5 rows\nsales_df.head(5)\n<\/pre><\/div>\n\n\n\n<p>You can also create a table manually:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=create(DATE, REGION, PRODUCT, AMOUNT, CUSTOMER).record( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [date(&#8220;2023-04-10&#8221;), &#8220;East&#8221;, &#8220;Laptop&#8221;, 1250, &#8220;TechCorp&#8221;, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; date(&#8220;2023-04-15&#8221;), &#8220;West&#8221;, &#8220;Monitor&#8221;, 450, &#8220;HomeOffice&#8221;]) &nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>When defining table structures, field names do not require quotes (more convenient than Python), and inserting records only requires flat collections. The output would be a table with two rows and five columns.<\/p>\n\n\n\n<p>The Python equivalent is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd\nfrom datetime import date\n\n# Create DataFrame manually\nsales_df = pd.DataFrame({\n    \"DATE\": [date(2023, 4, 10), date(2023, 4, 15)],\n    \"REGION\": [\"East\", \"West\"],\n    \"PRODUCT\": [\"Laptop\", \"Monitor\"],\n    \"AMOUNT\": [1250, 450],\n    \"CUSTOMER\": [\"TechCorp\", \"HomeOffice\"]\n})<\/pre><\/div>\n\n\n\n<p>While both table sequences in esProc SPL and <a href=\"https:\/\/www.w3schools.com\/python\/pandas\/pandas_dataframes.asp\" target=\"_blank\" rel=\"noreferrer noopener\">DataFrames<\/a> in Python serve as data structures for handling tabular data, they differ in key aspects. SPL&#8217;s table operates in a cell-based environment, where each step is explicitly named and can be referenced later, making it easier to track transformations. In contrast, Python&#8217;s pandas DataFrame relies on an object-based approach, where operations are performed directly on the DataFrame object.<\/p>\n\n\n\n<p>Another difference lies in column access: SPL allows you to reference column names directly in expressions, whereas pandas requires bracket notation (df[&#8220;column&#8221;]) or dot notation (df.column). Additionally, SPL follows a step-by-step execution model, making it easier to debug, while pandas often encourages method chaining, which can be more concise but harder to follow for complex transformations.<\/p>\n\n\n\n<p>The following flowchart illustrates the parallel workflows in SPL and Python for a typical data processing task, from importing raw data to analysis. While the overall flow is similar, the syntax and approach differ in important ways:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"948\" height=\"1011\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-65.png\" alt=\"Image of a flowchart which illustrates the parallel workflows in esProc SPL and Python for a typical data processing task - from importing raw data, to analysis.\" class=\"wp-image-108899\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-65.png 948w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-65-281x300.png 281w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-65-768x819.png 768w\" sizes=\"auto, (max-width: 948px) 100vw, 948px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-table-nbsp-properties-and-methods-in-esproc-spl\">Table&nbsp;properties and methods in esProc SPL<\/h3>\n\n\n\n<p>SPL provides various properties and methods to work with tables:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Sales data with 100 rows<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.len()<\/td><td>100<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 3<\/td><td>=A1.fname() [&#8220;DATE&#8221;, &#8220;REGION&#8221;, &#8220;PRODUCT&#8221;, &#8220;AMOUNT&#8221;, &#8220;CUSTOMER&#8221;]<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 4<\/td><td>=A1.fname(1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>&#8220;DATE&#8221;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 5<\/td><td>=A1.AMOUNT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>4<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output shows the number of rows, column names, the name of the first column, and the position of the AMOUNT column. These properties are useful for understanding the structure of your data.<\/p>\n\n\n\n<p>The equivalents in Python are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd\n\nsales_df = pd.read_csv(\"sales.csv\")\n# Number of rows\nrow_count = len(sales_df)\n# Get column names\ncolumn_names = sales_df.columns.tolist()\n# Get the name of the first column\nfirst_column = sales_df.columns[0]\n# Get the position of the AMOUNT column\namount_position = sales_df.columns.get_loc(\"AMOUNT\")<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-do-columns-and-rows-work-in-esproc-spl\">How do columns and rows work in esProc SPL?<\/h2>\n\n\n\n<p>esProc SPL provides powerful and intuitive ways to manipulate columns and rows in tables.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-rename-columns-in-esproc-spl\">How do you rename columns in esProc SPL?<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Sales data with 100 rows<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.rename(DATE:ORDER_DATE, AMOUNT:ORDER_AMOUNT)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Table with renamed columns &nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output of A2 would have columns renamed from DATE to ORDER_DATE and AMOUNT to ORDER_AMOUNT. This is useful when you want to make column names more descriptive or consistent.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"975\" height=\"140\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-66.png\" alt=\"An image showing the output of A2.\" class=\"wp-image-108900\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-66.png 975w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-66-300x43.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-66-768x110.png 768w\" sizes=\"auto, (max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p>The Python equivalent is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd\n\nsales_df = pd.read_csv(\"sales.csv\")\n\nsales_df = sales_df.rename(columns={\"DATE\": \"ORDER_DATE\", \"AMOUNT\": \"ORDER_AMOUNT\"})<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-calculate-column-statistics-in-esproc-spl\">How do you calculate column statistics in esProc SPL?<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.max(AMOUNT)<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 3<\/td><td>=A1.min(AMOUNT)<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 4<\/td><td>=A1.avg(AMOUNT)<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 5<\/td><td>=A1.sum(AMOUNT)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output shows various statistical calculations on the AMOUNT column. These methods provide a quick way to understand the distribution of your data.<\/p>\n\n\n\n<p>The equivalents in Python are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd  # Import the Pandas library\n\n# Load the sales dataset from a CSV file\nsales_df = pd.read_csv(\"sales.csv\")\n\n# Calculate the maximum, minimum, average, and total amount from the \"AMOUNT\" column\nmax_amount = sales_df[\"AMOUNT\"].max()  # Get the highest value\nmin_amount = sales_df[\"AMOUNT\"].min()  # Get the lowest value\navg_amount = sales_df[\"AMOUNT\"].mean()  # Get the average value\ntotal_amount = sales_df[\"AMOUNT\"].sum()  # Get the total sum\n\n# Print the results\nprint(\"Maximum Amount:\", max_amount)\nprint(\"Minimum Amount:\", min_amount)\nprint(\"Average Amount:\", avg_amount)\nprint(\"Total Amount:\", total_amount)<\/pre><\/div>\n\n\n\n<p>This script reads the sales.csv file, extracts values from the AMOUNT column, and performs basic statistical operations on them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-filter-rows-in-esproc-spl\">How do you filter rows in esProc SPL?<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>&nbsp;<\/strong><\/td><td><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/strong>A<\/td><\/tr><tr><td><strong>&nbsp;&nbsp; <\/strong>&nbsp;1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><\/tr><tr><td><strong>&nbsp;&nbsp;&nbsp;&nbsp;<\/strong>2<\/td><td><strong>=<\/strong>A1.select(AMOUNT&gt;1000)<\/td><\/tr><tr><td><strong>&nbsp;&nbsp;&nbsp; <\/strong>3<\/td><td>=A1.select(REGION==&#8221;East&#8221; &amp;&amp; PRODUCT==&#8221;Laptop&#8221;)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output of A2 would be a table with only rows where AMOUNT &gt; 1000, and A3 would show only rows where REGION is &#8220;East&#8221; and PRODUCT is &#8220;Laptop&#8221;. The `select` method is powerful for filtering data based on conditions.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"975\" height=\"513\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-67.png\" alt=\"\" class=\"wp-image-108906\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-67.png 975w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-67-300x158.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-67-768x404.png 768w\" sizes=\"auto, (max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"975\" height=\"510\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-68.png\" alt=\"\" class=\"wp-image-108907\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-68.png 975w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-68-300x157.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-68-768x402.png 768w\" sizes=\"auto, (max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p>The equivalents in Python are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd\n\n# Load the sales data from a CSV file\nsales_df = pd.read_csv(\"sales.csv\")\n\n# Filter rows where the AMOUNT column is greater than 1000\nfiltered_df1 = sales_df[sales_df[\"AMOUNT\"] &gt; 1000]\n\n# Filter rows where the REGION is \"East\" and the PRODUCT is \"Laptop\"\nfiltered_df2 = sales_df[(sales_df[\"REGION\"] == \"East\") &amp; (sales_df[\"PRODUCT\"] == \"Laptop\")]\n\n# Display the filtered data\nprint(filtered_df1)\nprint(filtered_df2)<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-sort-rows-in-esproc-spl\">How do you sort rows in esProc SPL?<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>&nbsp;<\/strong><\/td><td><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/strong>A<\/td><td><strong>&nbsp;<\/strong><\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><td>&nbsp;<\/td><\/tr><tr><td><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/strong>2<\/td><td>=A1.sort(AMOUNT)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Table sorted by AMOUNT (ascending)<\/td><\/tr><tr><td><strong>&nbsp;&nbsp;&nbsp;&nbsp; <\/strong>3<\/td><td>=A1.sort(AMOUNT:-1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Table sorted by AMOUNT (descending)<\/td><\/tr><tr><td><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/strong>4<\/td><td>=A1.sort(REGION,AMOUNT:-1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Table sorted by REGION (asc) then AMOUNT (desc)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output of each cell would be the sorted table according to the specified criteria. The `sort` method is flexible, allowing you to sort by multiple columns in different directions.<\/p>\n\n\n\n<p>The equivalents in Python are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd  # Import the pandas library\n\n# Load the sales data from a CSV file\nsales_df = pd.read_csv(\"sales.csv\")\n\n# Sort the DataFrame by the \"AMOUNT\" column in ascending order\nsorted_df1 = sales_df.sort_values(by=\"AMOUNT\")\n\n# Sort the DataFrame by the \"AMOUNT\" column in descending order\nsorted_df2 = sales_df.sort_values(by=\"AMOUNT\", ascending=False)\n\n# Sort the DataFrame first by \"REGION\" (ascending) and then by \"AMOUNT\" (descending)\nsorted_df3 = sales_df.sort_values(by=[\"REGION\", \"AMOUNT\"], ascending=[True, False])\n\n# Display the sorted DataFrames\nprint(\"Sorted by AMOUNT (Ascending):\")\nprint(sorted_df1)\n\nprint(\"\\nSorted by AMOUNT (Descending):\")\nprint(sorted_df2)\n\nprint(\"\\nSorted by REGION (Ascending) and AMOUNT (Descending):\")\nprint(sorted_df3)<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-limit-rows-in-esproc-spl\">How do you limit rows in esProc SPL?<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><td>&nbsp;<\/td><\/tr><tr><td>2<\/td><td>=A1.to(5)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>First 5 rows of the table<\/td><\/tr><tr><td>3<\/td><td>=A1.sort(AMOUNT:-1).to(5)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>five rows with highest AMOUNT values<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output of A2 would be the first five rows of the table, and A3 would be the five rows with the highest AMOUNT values. The `top` method is useful for limiting the number of rows in your result set.<\/p>\n\n\n\n<p>The equivalents in Python are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd  \n\n# Load the sales data from a CSV file  \nsales_df = pd.read_csv(\"sales.csv\")  \n\n# Retrieve the first 5 rows of the dataset  \nfirst_5_rows = sales_df.head(5)  \n\n# Sort the data by the \"AMOUNT\" column in descending order and get the top 5 entries  \ntop_5_by_amount = sales_df.sort_values(by=\"AMOUNT\", ascending=False).head(5)  \n\n# Display the results  \nprint(\"First 5 rows of the dataset:\")  \nprint(first_5_rows)  \nprint(\"\\nTop 5 rows sorted by AMOUNT in descending order:\")  \nprint(top_5_by_amount)  <\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-control-structures-loops-and-conditionals-in-esproc-spl-vs-python\">Control structures: loops and conditionals in esProc SPL vs. Python<\/h2>\n\n\n\n<p>esProc SPL provides familiar control structures for loops and conditionals, but with some syntax differences compared to Python.<\/p>\n\n\n\n<section id=\"my-first-block-block_26e738c9d7dde0642050da6d30bf994e\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Enjoying this article? Subscribe to the Simple Talk newsletter<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            Get selected articles, event information, podcasts and other industry content delivered straight to your inbox.                                    <\/div>\n            <\/div>\n                            <a href=\"https:\/\/www.red-gate.com\/simple-talk\/subscribe\/\" class=\"btn btn--secondary btn--lg\">Subscribe now<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-conditional-statements-work-in-esproc-spl\">How do conditional statements work in esProc SPL?<\/h3>\n\n\n\n<p>SPL uses <a href=\"https:\/\/www.w3schools.com\/python\/python_conditions.asp\" target=\"_blank\" rel=\"noreferrer noopener\">`if` statements<\/a> similar to many programming languages:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=1250&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>1250<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=if(A1&gt;1000,&#8221;High&#8221;,&#8221;Low&#8221;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>&#8220;High&#8221;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output shows that since A1 (1250) is greater than 1000, the result is &#8220;High.&#8221; The `if` function takes three arguments: a condition, a value to return if the condition is true, and a value to return if the condition is false.<\/p>\n\n\n\n<p>Another example:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.derive(if(AMOUNT&gt;2000:&#8221;Premium&#8221;,AMOUNT&gt;1000:&#8221;Standard&#8221;:&#8221;Basic&#8221;):CATEGORY)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output of A2 would include a new CATEGORY column with values based on the AMOUNT. This is a powerful way to categorize data based on multiple conditions.<\/p>\n\n\n\n<p>The equivalents in Python are:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd\nimport numpy as np  # Import NumPy for conditional logic\n\n# Define a single transaction amount\namount = 1250\n\n# Assign category based on amount using a conditional (ternary) operator\ncategory = \"High\" if amount &gt; 1000 else \"Low\"\n\n# Load the sales dataset from a CSV file\nsales_df = pd.read_csv(\"sales.csv\")\n\n# Apply conditional logic to classify sales amounts into categories\nsales_df[\"CATEGORY\"] = np.where(\n    sales_df[\"AMOUNT\"] &gt; 2000, \"Premium\",  # If amount is greater than 2000, label it as \"Premium\"\n    np.where(sales_df[\"AMOUNT\"] &gt; 1000, \"Standard\", \"Basic\")  # Else, categorize into \"Standard\" or \"Basic\"\n)\n\n# Display the first few rows to verify the changes\nprint(sales_df.head())<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-loops-work-in-esproc-spl\">How do loops work in esProc SPL?<\/h3>\n\n\n\n<p>esProc SPL provides several ways to implement loops:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-implement-for-loop-in-esproc-spl\">How do you implement &#8216;For Loop&#8217; in esProc SPL?<\/h3>\n\n\n\n<p>\u3010Looking at the Python code later, the equivalent SPL code only requires one line and doesn&#8217;t need loops.\u3011<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>A<\/td><\/tr><tr><td>1<\/td><td>=5.(~*2+1)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u3010If using &#8216;for&#8217;, it needs to be written across multiple lines; &#8216;for&#8217; is a keyword and shouldn&#8217;t be preceded by &#8216;=&#8217;.\u3011<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>A<\/td><td>B<\/td><\/tr><tr><td>1<\/td><td>=[]<\/td><td>&nbsp;<\/td><\/tr><tr><td>2<\/td><td>for 5<\/td><td>=A2*2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Current value * 2<\/td><\/tr><tr><td>3<\/td><td>&nbsp;<\/td><td>=B2+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B2 + 1<\/td><\/tr><tr><td>4<\/td><td>&nbsp;<\/td><td>&gt;A1=A1|B3 \u3010This sentence is equivalent to Python\u2019s append, and the result is stored in A1.\u3011<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This loop iterates from 1 to 5, multiplies each value by 2, adds 1, and returns the result. The `for@r` function creates a loop that returns a sequence of values. The `&gt;` symbol indicates that the line is part of the loop body.<\/p>\n\n\n\n<p>The equivalent in Python is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">result = []  # Initialize an empty list to store results\n\nfor i in range(1, 6):  # Loop through numbers 1 to 5\n    value = i * 2      # Multiply the number by 2\n    value = value + 1  # Add 1 to the result\n    result.append(value)  # Append the final value to the list\n\nprint(result)  # Output: [3, 5, 7, 9, 11]<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-loop-through-a-table-in-esproc-spl\">How do you loop through a table in esProc SPL?<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.select(AMOUNT&gt;1000)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>26 rows where AMOUNT &gt; 1000<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3<\/td><td>=A2.(CUSTOMER + &#8221; purchased &#8221; + PRODUCT + &#8221; for $&#8221; + string(AMOUNT) ) &nbsp; &nbsp;<\/td><td>&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This loop function in A3 iterates through the filtered table, creates a formatted string for each row, and adds it to a sequence.<\/p>\n\n\n\n<p>The equivalent in Python is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd  # Import the pandas library\n\n# Read the sales data from a CSV file into a DataFrame\nsales_df = pd.read_csv(\"sales.csv\")\n\n# Filter rows where the AMOUNT column is greater than 1000\nfiltered_df = sales_df[sales_df[\"AMOUNT\"] &gt; 1000]\n\n# Create a list to store formatted messages\nresult = [\n    f\"{row['CUSTOMER']} purchased {row['PRODUCT']} for ${row['AMOUNT']}\"\n    for _, row in filtered_df.iterrows()\n]\n\n# Print the result\nfor message in result:\n    print(message)<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-does-the-case-function-work-in-esproc-spl\">How does the case function work in esProc SPL?<\/h2>\n\n\n\n<p>SPL provides a `case` function for multiple conditions:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=&#8221;Laptop&#8221;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=case(A1,&#8221;Laptop&#8221;:&#8221;Electronic&#8221;,&#8221;Monitor&#8221;:&#8221;Display&#8221;,&#8221;Printer&#8221;:&#8221;Output&#8221;,&#8221;Unknown&#8221;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Electronic&#8221;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output shows that since A1 is &#8220;Laptop,&#8221; the result is &#8220;Electronic.&#8221; The `case` function takes a value to test, followed by pairs of values and results, with an optional default value at the end.<\/p>\n\n\n\n<p>The equivalent in Python is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \"># Define the product\nproduct = \"Laptop\"\n\n# Use a dictionary to map product names to categories\ncategory = {\n    \"Laptop\": \"Electronic\",\n    \"Monitor\": \"Display\",\n    \"Printer\": \"Output\"\n}.get(product, \"Unknown\")  # If product is not found, return \"Unknown\"\n\n# Print the category\nprint(category)  # Output: Electronic<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"788\" height=\"497\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-69.png\" alt=\"This flowchart illustrates the control flow structures in SPL, showing how conditional logic and looping structures work together to process data and return results.\" class=\"wp-image-108908\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-69.png 788w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-69-300x189.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-69-768x484.png 768w\" sizes=\"auto, (max-width: 788px) 100vw, 788px\" \/><figcaption class=\"wp-element-caption\">This flowchart illustrates the control flow structures in SPL, showing how conditional logic and looping structures work together to process data and return results.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-do-functions-and-procedures-work-in-esproc-spl\">How do functions and procedures work in esProc SPL?<\/h2>\n\n\n\n<p>esProc SPL allows you to define custom <a href=\"https:\/\/adacomputerscience.org\/concepts\/sub_proc_fun\" target=\"_blank\" rel=\"noreferrer noopener\">functions and procedures<\/a> to encapsulate logic and make your code more modular and reusable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-define-functions-in-esproc-spl\">How do you define functions in esProc SPL?<\/h3>\n\n\n\n<p>In SPL, you can define functions using the `function` keyword:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>B<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=func Add_number(x,y)<\/td><td>=x+y<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>A custom function requires at least two columns and does not need to include &#8216;return&#8217;. This defines a function that adds two numbers. To use this function:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=Add_number(5,3)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output shows that the function correctly adds 5 and 3 to produce 8. Functions in SPL can take parameters and return values, just like in Python.<\/p>\n\n\n\n<p>The Python equivalent is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">def add_numbers(x, y):\n    \"\"\"Returns the sum of two numbers.\"\"\"\n    return x + y\n\n# Call the function with arguments 5 and 3\nresult = add_numbers(5, 3)  \n\n# Print the result\nprint(result)  # Output: 8<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-functions-with-tables-work-in-esproc-spl\">How do functions with tables work in esProc SPL?<\/h3>\n\n\n\n<p>Functions can also work with tables:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>A<\/td><td>B<\/td><td>&nbsp;<\/td><\/tr><tr><td>1<\/td><td>=func analyze_sales(ds, min_amount)<\/td><td>=ds.select(AMOUNT&gt;=min_amount)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Filter for amounts &gt;= min_amount<\/td><\/tr><tr><td>2<\/td><td>&nbsp;<\/td><td>=B1.groups(REGION;count():COUNT,sum(AMOUNT):TOTAL)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Group by region &nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This function filters a table for amounts greater than or equal to a minimum value, then groups by region and calculates counts and totals. To use this function:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 3<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp; 4<\/td><td>=analyze_sales(A4, 1000)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Filtered and grouped sales data<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This example demonstrates how functions can encapsulate complex data processing logic, making your code more modular and reusable.<\/p>\n\n\n\n<p>The Python equivalent is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">import pandas as pd  # Import the pandas library\n\ndef analyze_sales(df, min_amount):\n    \"\"\"\n    Filters sales data based on a minimum amount and aggregates results by region.\n\n    Parameters:\n    df (DataFrame): The input sales data.\n    min_amount (int or float): The minimum amount to filter sales.\n\n    Returns:\n    DataFrame: Aggregated sales data grouped by region.\n    \"\"\"\n    # Filter rows where the AMOUNT is greater than or equal to the minimum amount\n    filtered_df = df[df[\"AMOUNT\"] &gt;= min_amount]\n    \n    # Group by REGION and calculate COUNT (number of transactions) and TOTAL (sum of AMOUNT)\n    result = filtered_df.groupby(\"REGION\").agg(\n        COUNT=(\"AMOUNT\", \"count\"),  # Count of transactions\n        TOTAL=(\"AMOUNT\", \"sum\")     # Sum of AMOUNT for each region\n    ).reset_index()  # Reset index for a cleaner DataFrame\n    \n    return result\n\n# Load sales data from a CSV file\nsales_df = pd.read_csv(\"sales.csv\")\n\n# Analyze sales with a minimum transaction amount of 1000\nresult = analyze_sales(sales_df, 1000)\n\n# Display the result\nprint(result)<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-lambda-functions-work-in-esproc-spl\">How do lambda functions work in esProc SPL?<\/h3>\n\n\n\n<p>SPL also supports lambda functions for concise, inline function definitions:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=[1,2,3,4,5]<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.(~*2)<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp; [2,4,6,8,10]<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>In SPL, lambda doesn&#8217;t require parameter definition &#8211; just use ~ directly.<\/p>\n\n\n\n<p>The output shows that each value in the sequence is doubled. The `map` function applies a lambda function to each element of a sequence and returns a new sequence with the results.<\/p>\n\n\n\n<p>The equivalent in Python is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \"># Define a list of numbers\nnumbers = [1, 2, 3, 4, 5]\n\n# Use map with a lambda function to double each number\ndoubled = list(map(lambda x: x * 2, numbers))\n\n# Print the result\nprint(doubled)  # Output: [2, 4, 6, 8, 10]<\/pre><\/div>\n\n\n\n<p>This code correctly applies the lambda function to each element in the numbers, doubling their values.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-esproc-spl-error-handling-and-debugging-techniques\">esProc SPL error handling and debugging techniques<\/h2>\n\n\n\n<p>Effective error handling and debugging are essential skills for any data analyst. esProc SPL provides several techniques for handling errors and debugging your code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-handle-errors-in-esproc-spl\">How do you handle errors in esProc SPL?<\/h3>\n\n\n\n<p>The correct approach to handle errors in esProc SPL is to use an `if` condition, or check for errors manually. It provides an `error()` function to trigger an error and `string(e)` to capture error messages.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 1<\/td><td>=if(0!=0,1\/0,&#8221;Error: Division by zero&#8221;)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The output would be:<\/p>\n\n\n\n<p>A1: Error: Division by zero<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"975\" height=\"96\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-70.png\" alt=\"An image showing what the output would be.\" class=\"wp-image-108909\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-70.png 975w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-70-300x30.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/02\/image-70-768x76.png 768w\" sizes=\"auto, (max-width: 975px) 100vw, 975px\" \/><\/figure>\n\n\n\n<p>The equivalent in Python is:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">try:\n    result = 1 \/ 0  # This will cause a division by zero error\n    message = \"Success\"  # This line will not execute due to the error\nexcept Exception as e:\n    message = f\"Error: {e}\"  # Catch the exception and store the error message\n\nprint(message)  # Output: Error: division by zero<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-do-you-use-the-debug-panel-in-esproc-spl\">How do you use the debug panel in esProc SPL?<\/h3>\n\n\n\n<p>The esProc&nbsp;IDE provides a debug panel that helps you troubleshoot scripts efficiently. You can set breakpoints by clicking in the margin next to the cell where you want execution to pause. Once breakpoints are set, clicking the &#8220;Debug&#8221; button starts the debugging process. The IDE offers step buttons that allow you to execute the code incrementally, making it easier to identify issues in complex scripts with multiple functions and procedures. <\/p>\n\n\n\n<p>Additionally, the debug panel displays variable values, enabling you to inspect their states at each step. The feature is useful when dealing with intricate calculations or logical conditions, as it allows for a clear understanding of how data changes throughout execution.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-solve-common-esproc-spl-errors\">How to solve common esProc SPL errors<\/h3>\n\n\n\n<p>Here are some common errors you might encounter in SPL and how to solve them:<\/p>\n\n\n\n<p>1. <strong>Column Not Found<\/strong>: This occurs when you reference a column that doesn&#8217;t exist in your table.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.select(SALES_AMOUNT&gt;1000)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>Error: Column SALES_AMOUNT not found &nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Solution: Check your column names and make sure you&#8217;re using the correct ones. You can use `A1.fields` to see the available columns.<\/p>\n\n\n\n<p>2. <strong>Null Value Errors<\/strong>: These occur when you try to perform operations on null values.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>&nbsp;<\/td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<\/td><td>=file(&#8220;document\/sales.csv&#8221;).import@ct()<\/td><td>&nbsp;<\/td><\/tr><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<\/td><td>=A1.derive(if(PROMO_CODE==null,0,0.1*AMOUNT):DISCOUNT:)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/td><td>New column with discount &nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Solution: Use the `if` function to handle null values, or check for null values explicitly as shown in the example.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-summary-and-next-steps\">Summary and next steps<\/h2>\n\n\n\n<p>In this comprehensive guide &#8211; part 2 of the series &#8211; we&#8217;ve explored the fundamental syntax and data structures of esProc SPL. From basic syntax elements to complex data manipulations, SPL provides a powerful and intuitive language for data analysis tasks.<\/p>\n\n\n\n<p>The table data structure offers a flexible and efficient way to work with tabular data, with a set of methods for filtering, transforming, and aggregating data. The cell-based structure of SPL scripts creates a visual flow of data processing steps, making it easier to understand and debug complex transformations.<\/p>\n\n\n\n<p>Control structures like conditionals and loops allow you to create more complex data processing logic, while custom functions help you encapsulate reusable code. Error handling and debugging features provide the tools you need to identify and fix issues in your scripts.<\/p>\n\n\n\n<p>As you continue your journey with esProc SPL, you&#8217;ll discover more advanced features and techniques that can further enhance your data analysis capabilities. In the next article, we&#8217;ll look at data manipulation techniques in SPL, including complex transformations, window functions, and more data analysis methods.<\/p>\n\n\n\n<p>And remember: the best way to learn SPL is through practice. Try rewriting some of your Python data analysis scripts in SPL, and see how the different approach might simplify your workflow or provide new insights into your data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-further-reading-to-advance-your-esproc-spl-knowledge\">Further reading to advance your esProc SPL knowledge<\/h2>\n\n\n\n<p>To deepen your understanding of esProc SPL and data analysis, consider looking at these resources:<\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/pandas.pydata.org\/docs\/\" target=\"_blank\" rel=\"noreferrer noopener\">Python Pandas Documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.geeksforgeeks.org\/python-data-analysis-using-pandas\/\" target=\"_blank\" rel=\"noreferrer noopener\">Data analysis with Python and Pandas<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/blog.esproc.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">esProc SPL Official Documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.stitchdata.com\/resources\/data-analysis-tools\/#:~:text=24.-,Excel,native%20programming%20language%2C%20Visual%20Basic.\" target=\"_blank\" rel=\"noreferrer noopener\">Comparing Data Processing Tools<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>Frequently asked questions (FAQs)<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. Is esProc SPL similar to Python in syntax?<\/h3>\n            <div class=\"faq-answer\">\n                <p>While esProc SPL shares some similarities with Python, such as method chaining and intuitive function names, it has its own syntax optimized for data processing. SPL uses cell references (A1, B1, etc.) instead of variable names, and its syntax is designed to make data transformation steps more readable and concise.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. What is a table sequence in esProc SPL, and how does it compare to a DataFrame (Python)?<\/h3>\n            <div class=\"faq-answer\">\n                <p>A table sequence in esProc SPL is the primary data structure, similar to a DataFrame in pandas. Both are two-dimensional structures with rows and columns. However, table sequences in SPL don&#8217;t have separate index and column labels like DataFrames do. Table sequences are optimized for data processing operations and integrate seamlessly with SPL&#8217;s syntax for efficient data manipulation.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. Can I write functions in esProc SPL?<\/h3>\n            <div class=\"faq-answer\">\n                <p>esProc SPL allows you to define custom functions, which you can then use throughout your scripts. These functions can take parameters, perform calculations, and return results, much like functions in Python. This feature allows you to encapsulate reusable logic and create more modular, maintainable code in your data analysis projects.<\/p>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>Explore esProc SPL&#8217;s syntax and data structures. Learn how it compares to Python and discover its scripting capabilities for efficient data analysis.&hellip;<\/p>\n","protected":false},"author":342096,"featured_media":105342,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143526,53,146042],"tags":[159117,159374,5021],"coauthors":[159002],"class_list":["post-108897","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development","category-featured","category-python","tag-esproc-spl","tag-moving-from-python-to-esproc-spl","tag-python"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/108897","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/342096"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=108897"}],"version-history":[{"count":7,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/108897\/revisions"}],"predecessor-version":[{"id":108919,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/108897\/revisions\/108919"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/105342"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=108897"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=108897"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=108897"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=108897"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}