{"id":1032,"date":"2026-08-11T14:27:38","date_gmt":"2026-08-11T18:27:38","guid":{"rendered":"https:\/\/deftstrokesdev.com\/?page_id=1032"},"modified":"2026-08-11T16:27:44","modified_gmt":"2026-08-11T20:27:44","slug":"giql","status":"publish","type":"page","link":"https:\/\/deftstrokesdev.com\/index.php\/giql\/","title":{"rendered":"LLM guidance for creating Generic Inquiries with GIQL"},"content":{"rendered":"\n\n\n<style>\n.ds-markdown-wrap {\n  max-width: 1092px;\n  margin: 0 auto;\n  padding: 64px 20px;\n  box-sizing: border-box;\n}\n.ds-markdown-title {\n  text-align: center;\n  font-family: Helvetica, Arial, sans-serif;\n  font-weight: 700;\n  font-size: 32px;\n  line-height: 1.25;\n  color: var(--theme-palette-color-5, #faf8f4);\n  margin: 0 0 32px;\n}\n.ds-markdown-panel {\n  position: relative;\n}\n.ds-markdown-raw {\n  display: block;\n  font-family: 'Oxygen Mono', monospace;\n  font-size: 14px;\n  line-height: 1.6;\n  color: rgba(250,248,244,0.85);\n  background: var(--theme-palette-color-3, #3f4245);\n  border-radius: 8px;\n  padding: 24px 28px;\n  white-space: pre-wrap;\n  word-wrap: break-word;\n  overflow-x: auto;\n}\n.ds-markdown-copy-btn {\n  position: absolute;\n  top: 12px;\n  right: 12px;\n  font: 600 13px\/1 Helvetica, Arial, sans-serif;\n  color: var(--theme-palette-color-4, #111518);\n  background: var(--theme-palette-color-1, #a8977b);\n  border: none;\n  border-radius: 8px;\n  padding: 6px 14px;\n  cursor: pointer;\n}\n.ds-markdown-copy-btn:hover {\n  background: var(--theme-palette-color-2, #7f715c);\n}\n<\/style>\n\n<div class=\"ds-markdown-wrap\">\n  <h1 class=\"ds-markdown-title\">LLM guidance for creating Generic Inquiries with GIQL<\/h1>\n  <div class=\"ds-markdown-panel\">\n    <button type=\"button\" class=\"ds-markdown-copy-btn\" id=\"ds-markdown-copy\">Copy<\/button>\n    <pre><code class=\"ds-markdown-raw\" id=\"ds-markdown-content\"><\/code><\/pre>\n  <\/div>\n<\/div>\n\n<script type=\"text\/plain\" id=\"ds-markdown-source\">\n\n## GIQL Basic Syntax\n\nGIQL follows SQL clause order but starts with `FROM`, and `SELECT` comes last:\n\n```\n[DECLARE ...]\nFROM [Namespace.PrimaryDAC] AS Alias\n[JOIN [Namespace.SecondaryDAC] AS Alias2 ON ...]\n[WHERE ...]\n[GROUP BY ...]\n[ORDER BY ...]\n[SELECT ...]\n```\n\nIf `SELECT` is omitted, all fields from all DACs are included in results.\n\nField references use `DAC.PropertyName` (PascalCase, matching the C# property \u2014 not the abstract class name). DAC names are the class name without namespace. Exception: `DECLARE ... SCHEMA` references use the DAC's camelCase BQL field name instead \u2014 see \u00a713.\n\n### Every table reference must be fully qualified and aliased\n\nEvery DAC referenced anywhere in the query \u2014 including the primary `FROM` table, not just joined tables \u2014 must use its fully qualified namespace in brackets and an `AS alias`, even when the alias just repeats the DAC name (e.g. `FROM [PX.Objects.AR.ARRegister] AS ARRegister`). Once aliased, use the alias (not the bare DAC name) in `ON`, `WHERE`, `ORDER BY`, `GROUP BY`, and `SELECT`. A joined Generic Inquiry (sub-GI) uses the same bracket form with a synthetic `GI` namespace, e.g. `INNER JOIN [GI.GI-FirstInvoice_SubGI] AS GIFirstInvoice`.\n\n### Supported clauses\n\n- `FROM` \u2014 primary DAC (required). Must be fully qualified with namespace in brackets and given an `AS alias` (e.g. `FROM [PX.Objects.AR.ARRegister] AS ARRegister`).\n- `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL JOIN` \u2014 with `ON` conditions. Same rule as `FROM`: joined DACs must be fully qualified with namespace in brackets and must have an `AS alias` (e.g. `LEFT JOIN [PX.Objects.AP.APVendorPrice] AS HigherBreak`). `ON` supports the same `AND`\/`OR`\/`NOT`\/parentheses logic as `WHERE`.\n- `WHERE` \u2014 filtering, supports `AND`, `OR`, `NOT`, parentheses\n- `GROUP BY` \u2014 grouping. Recommended whenever `SELECT` contains an aggregate (`SUM`, `MAX`, `MIN`, `AVG`, `COUNT`): list every non-aggregated column that appears in `SELECT`. In practice, an omitted non-aggregated column gets auto-wrapped in `MAX()`\/`SUM()` rather than raising an error (see \u00a711 gotcha 5) \u2014 and real usage has been observed omitting columns that are functionally dependent on the group key (e.g. grouping by `Customer.BAccountID` while selecting un-aggregated `Customer.AcctCD`\/`Customer.AcctName`). Don't rely on this \u2014 list columns explicitly unless you've confirmed the omission is safe.\n- `ORDER BY` \u2014 with `ASC`\/`DESC`. Comes after `GROUP BY`. Accepts formula expressions (`{= }`), not just plain field references \u2014 see \u00a714.\n- `SELECT` \u2014 result columns, supports aggregates (`SUM`, `MAX`, `MIN`, `AVG`, `COUNT`) and aliases (`AS 'Caption'`)\n\n---\n\n## GIQL Parameters \u2014 DECLARE\n\nParameters must be declared with `DECLARE` before the `FROM` clause. Without `DECLARE`, the GIQL editor will treat unqualified names as unresolved entity aliases.\n\n### DECLARE syntax\n\n```\nDECLARE parameter_name\n  SCHEMA schema_reference\n  [ <Checkbox> | <Combobox> ( 'key' : 'value', ... ) ]\n  [ DEFAULT default_value ]\n  [ AS 'display_name' ]\n  [ REQUIRED ]\n  [ HIDDEN ]\n```\n\n- `SCHEMA [Namespace.DAC].field` \u2014 inherits the field's type, selector control, and validation from the DAC. The DAC must be fully qualified with its namespace in square brackets (e.g. `[PX.Objects.PO.POOrder].vendorID`, not `POOrder.VendorID`). This gives the parameter the same lookup\/dropdown behavior as the original field. The field you reference determines the selector: use the CD field (e.g. `Vendor.acctCD`, `InventoryItem.inventoryCD`) to get the source DAC's selector, or a foreign key ID field (e.g. `POOrder.vendorID`) to get the selector defined on that FK reference. Pick whichever gives the lookup control you want. Note the field name here is the DAC's camelCase BQL field name (matching the nested `Field<>` class, e.g. `creditDaysPastDue`), not the PascalCase C# property (`CreditDaysPastDue`) used everywhere else in GIQL.\n- `Checkbox` \u2014 renders as a checkbox parameter.\n- `Combobox ('key' : 'value', ...)` \u2014 renders as a dropdown with fixed key\/value pairs.\n- `DEFAULT value` \u2014 pre-fills the parameter. Written as a quoted string literal even for numeric\/date fields (e.g. `DEFAULT '5'` for an `Int16` field) \u2014 GIQL doesn't use a bare numeric literal here.\n- `AS 'label'` \u2014 display name in the Selection area.\n- `REQUIRED` \u2014 parameter must have a value; the GI won't execute without it.\n- `HIDDEN` \u2014 parameter exists but is not shown in the Selection area (useful for parameters set programmatically, e.g. from side panel navigation).\n\n### Referencing parameters in formulas\nDeclared parameters can be used inside `{= }` formulas with the same `[ ]` bracket syntax as DAC fields, including arithmetic: `{=DateAdd(Today(),'y',[Within]*-1)}`.\n\n### Optional filter pattern\n\nThe standard pattern for optional parameters uses `IS NULL OR` in the `WHERE` clause:\n\n```\nDECLARE VendorID SCHEMA [PX.Objects.AP.Vendor].bAccountID AS 'Vendor'\n\nFROM [PX.Objects.PO.POOrder] AS POOrder\nWHERE (VendorID IS NULL OR POOrder.VendorID = VendorID)\n```\n\nIf the user leaves the parameter blank, the condition is skipped. If they fill it in, it filters.\n\n---\n\n## GIQL Key Differences from SQL\n\n- Query starts with `FROM`, not `SELECT`\n- References DAC class names and property names, not database tables\/columns\n- Every table reference \u2014 the primary `FROM` DAC and every `JOIN` \u2014 must be fully qualified with its namespace in brackets and given an `AS alias`; there is no bare-name shorthand like plain BQL\/SQL allows\n- Another GI can be used as a data source (like a SQL view)\n- Parameters must be declared with `DECLARE` before `FROM`\n- String literals use single quotes, whether written bare (`'A'`) or inside a formula (`{='PMT'}`)\n- A condition value comes from one of two designer input modes, which compile to different GIQL text: **Formula** (free-form expression) compiles wrapped in `{= }` \u2014 e.g. `Field = {=0}`, `Field <= {=Today()}`, `DocType = {='PMT'}`. **From Schema** (pick a curated value from the field's own value list) compiles as a bare literal \u2014 e.g. `Status = 'A'` (the stored value behind the curated 'Active' caption), `Released = True`, `Voided != True` (the curated `True`\/`False` options for a boolean-schema field). Both are valid GIQL text, but they aren't interchangeable stylistic choices \u2014 the bare form only applies when the value is genuinely one of the field's own curated options.\n- Built-in variables use `@` prefix in `SELECT`: `@Today`, `@BusinessDate`. In `ON`\/`WHERE` clauses, use `{=Today()}` instead.\n- Write `GROUP BY` explicitly whenever `SELECT` contains an aggregate \u2014 see \u00a712 for how strictly the \"list every non-aggregated column\" guidance is actually enforced\n- The GIQL editor provides IntelliSense, infotips, and real-time validation\n- A GI can be referenced as a data source using quotes or a bracketed `GI.` namespace: `FROM 'My GI Name'` or `FROM [GI.GI-FirstInvoice_SubGI] AS GIFirstInvoice`\n\n### Formulas in SELECT and ORDER BY\n\nFormula columns use `{=expression}` syntax. In `SELECT`, follow the formula with a `SCHEMA` reference (for data type\/formatting) and an `AS` alias; in `ORDER BY`, the formula stands alone since there's no result column to type or caption:\n\n```\nSELECT POLine.OrderQty,\n       POLine.CuryUnitCost,\n       {=[POLine.OrderQty]*[POLine.CuryUnitCost]} SCHEMA [PX.Objects.PO.POLine].curyExtCost AS 'Ext Cost'\n\nORDER BY {=DateDiff('m',[GIFirstInvoice.ARInvoice_docDate],Today())\/12.0} DESC\n```\n\n- The `{= }` wrapper is required around the entire formula expression\n- Inside the formula, DAC fields use `[DAC.Field]` bracket syntax; declared `DECLARE` parameters use the same bracket syntax (e.g. `[Within]*-1`) and support arithmetic\n- `SCHEMA [Namespace.DAC].field` (camelCase BQL field name, same convention as \u00a713) determines formatting for a `SELECT` formula column \u2014 pick a field whose type matches the formula's output. Omit it in `ORDER BY`.\n- Literal values inside formulas use bare values: `0`, `100`, `'text'` \u2014 no `{= }` nesting\n- `IIf(condition, true_value, false_value)` for conditional logic; nest for multiple branches\n- A joined sub-GI's fields have shown up under two different names in the same query \u2014 the sub-GI's own exposed name (`GIFirstInvoice.DocDate`, in `SELECT`) and the underlying `{ObjectName}_{field}` name from \u00a75 (`GIFirstInvoice.ARInvoice_docDate`, in `ORDER BY`, `field` in camelCase). Which form is available\/required in which clause hasn't been fully mapped \u2014 verify against the sub-GI's own `SELECT` projection when a plain alias reference doesn't resolve.\n\n\n\n<\/script>\n\n<script>\n(function() {\n  var source = document.getElementById('ds-markdown-source');\n  var target = document.getElementById('ds-markdown-content');\n  if (source && target) {\n    target.textContent = source.textContent.trim();\n  }\n\n  var copyBtn = document.getElementById('ds-markdown-copy');\n  if (copyBtn && target) {\n    copyBtn.addEventListener('click', function() {\n      var text = target.textContent;\n      var showCopied = function() {\n        var original = copyBtn.textContent;\n        copyBtn.textContent = 'Copied';\n        setTimeout(function() { copyBtn.textContent = original; }, 1500);\n      };\n      if (navigator.clipboard && navigator.clipboard.writeText) {\n        navigator.clipboard.writeText(text).then(showCopied);\n      } else {\n        var ta = document.createElement('textarea');\n        ta.value = text;\n        ta.style.position = 'fixed';\n        ta.style.opacity = '0';\n        document.body.appendChild(ta);\n        ta.select();\n        document.execCommand('copy');\n        document.body.removeChild(ta);\n        showCopied();\n      }\n    });\n  }\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>LLM guidance for creating Generic Inquiries with GIQL Copy<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_monsterinsights_skip_tracking":false,"footnotes":""},"class_list":["post-1032","page","type-page","status-publish","hentry"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":8}},"_links":{"self":[{"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/pages\/1032","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/comments?post=1032"}],"version-history":[{"count":8,"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/pages\/1032\/revisions"}],"predecessor-version":[{"id":1042,"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/pages\/1032\/revisions\/1042"}],"wp:attachment":[{"href":"https:\/\/deftstrokesdev.com\/index.php\/wp-json\/wp\/v2\/media?parent=1032"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}