{"id":22906654,"url":"https://github.com/squashql/squashql","last_synced_at":"2025-12-24T14:25:11.746Z","repository":{"id":154164718,"uuid":"447877689","full_name":"squashql/squashql","owner":"squashql","description":"Official repository of SquashQL, the SQL query engine for multi-dimensional and hierarchical analysis that empowers your SQL database","archived":false,"fork":false,"pushed_at":"2024-12-03T07:18:51.000Z","size":2640,"stargazers_count":51,"open_issues_count":9,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-12-08T12:09:45.354Z","etag":null,"topics":["bigquery","clickhouse","database","duckdb","java","jdbc","query","querybuilder","snowflake","spark","sql","typescript"],"latest_commit_sha":null,"homepage":"https://www.squashql.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/squashql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-01-14T07:22:58.000Z","updated_at":"2024-12-06T16:57:58.000Z","dependencies_parsed_at":"2023-10-11T07:37:48.913Z","dependency_job_id":"9fc390ad-1b43-4264-88e7-07508ada8ad3","html_url":"https://github.com/squashql/squashql","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squashql%2Fsquashql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squashql%2Fsquashql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squashql%2Fsquashql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squashql%2Fsquashql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/squashql","download_url":"https://codeload.github.com/squashql/squashql/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229640460,"owners_count":18102846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bigquery","clickhouse","database","duckdb","java","jdbc","query","querybuilder","snowflake","spark","sql","typescript"],"created_at":"2024-12-14T03:01:05.102Z","updated_at":"2025-12-24T14:25:11.732Z","avatar_url":"https://github.com/squashql.png","language":"Java","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg width=\"512\" src=\"./documentation/assets/logo_horizontal.svg\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/squashql/squashql/actions\"\u003e\n    \u003cimg src=\"https://github.com/squashql/squashql/actions/workflows/ci.yml/badge.svg?branch=main\" alt=\"Github Actions Badge\"\u003e\n  \u003c/a\u003e\n  \u003ca\u003e\n    \u003cimg alt=\"GitHub commit activity\" src=\"https://img.shields.io/github/commit-activity/m/squashql/squashql\"\u003e\n  \u003c/a\u003e\n  \u003ca\u003e\n    \u003cimg alt=\"Discord chat\" src=\"https://img.shields.io/discord/1051535068637700196?label=discord\"\u003e\n  \u003c/a\u003e \n\u003c/p\u003e\n\n\u003ch4 align=\"center\"\u003e\n  \u003ca href=\"https://github.com/squashql/squashql#-key-features\"\u003eKey features\u003c/a\u003e |\n  \u003ca href=\"https://github.com/squashql/squashql-showcase\"\u003eTutorial\u003c/a\u003e |\n  \u003ca href=\"https://github.com/squashql/squashql#-documentation\"\u003eDocs\u003c/a\u003e |\n  \u003ca href=\"https://github.com/squashql/squashql#-resources\"\u003eResources\u003c/a\u003e |\n  \u003ca href=\"https://discord.gg/p7dg2wEwFs\"\u003eChat\u003c/a\u003e\n\u003c/h4\u003e\n\u003cbr/\u003e\n\n---\n\nSquashQL is an open-source SQL query engine designed to streamline the process of building multi-dimensional queries.\nAt its core, it acts as a middleware layer that stands between SQL databases and multiple clients or front-end\napplications.\nThe primary objective is twofold: to empower back-end developers in optimizing SQL database usage and to provide\nfront-end developers with an intuitive API for configuring metrics in the UI.\n\nIt follows a \"write once, run everywhere\" philosophy, making it an excellent solution for scenarios where data needs to \nbe efficiently queried from multiple databases. Currently, SquashQL supports compatibility with databases such as Apache Spark,\nClickHouse, BigQuery, Snowflake, PostgreSQL and DuckDB.\n\n## 💡 Key features\n\n### Simple API\n\nTypescript SQL-like query builder available on [npm](https://www.npmjs.com/package/@squashql/squashql-js). This empowers developers to construct and execute SQL queries directly\nfrom their applications, utilizing a syntax that feels familiar and expressive.\n\n```typescript\nimport {\n  from, avg, TableField\n} from \"@squashql/squashql-js\"\n\nclass Orders {\n  readonly _name: string = \"Orders\"\n  readonly customer_id: TableField = new TableField(\"Orders.customer_id\")\n  readonly amount: TableField = new TableField(\"Orders.amount\")\n}\n\nconst orders = new Orders()\n\nconst q = from(orders._name)\n        .select([orders.customer_id], [], [avg(\"average_spends\", orders.amount)])\n        .build()\n```\n\n[Full API documentation](documentation/QUERY.md)\n\n### Pivot Table\n\nCreate pivot table in SQL with a simple and intuitive syntax. Totals and subtotals **are computed by the database**.\n\n```typescript\nconst pivotConfig: PivotConfig = {\n  rows: [sales.product, sales.region],\n  columns: [sales.month]\n}\nconst query = from(sales._name)\n        .select([sales.product, sales.region, sales.month], [], [sum(\"sales\", sales.revenue)])\n        .build()\nquerier.executePivotQuery(query, pivotConfig)\n```\n\n\u003cimg src=\"documentation/assets/pivot-table-sales.png\" width=\"500\"\u003e\n\n👉 https://jsfiddle.net/azeq/c6f9ox4u/\n\nTry the [tutorial](https://github.com/squashql/squashql-showcase/blob/main/TUTORIAL.md#pivot-table) to build your own pivot table.\n\n### Bucketing\n\nBucketing, also known as binning or discretization, is a technique used in data analysis to group continuous or\nnumerical data into discrete intervals or \"buckets.\"\n\n\u003cdetails\u003e\u003csummary\u003eSQL\u003c/summary\u003e\n\n```sql\n-- Create a sample employees table\nCREATE TABLE employees\n(\n  employee_id   INT PRIMARY KEY,\n  employee_name VARCHAR(255),\n  salary        DECIMAL(10, 2),\n  age           INT\n);\n-- Insert some sample data\nINSERT INTO employees (employee_id, employee_name, salary, age)\nVALUES (1, 'John Doe', 50000.00, 50),\n       (2, 'Jane Smith', 65000.00, 33),\n       (3, 'Bob Johnson', 80000.00, 42),\n       (4, 'Alice Brown', 40000.00, 21),\n       (5, 'Peter Parker', 61000.00, 55),\n       (6, 'Jack Black', 73000.00, 39),\n       (7, 'Nicole Williams', 44000.00, 25),\n       (8, 'Charlie Wilson', 72000.00, 28);\n```\n\n\u003c/details\u003e\n\nData:\n```\n+-------------+-----------------+---------+-----+\n| employee_id |   employee_name |  salary | age |\n+-------------+-----------------+---------+-----+\n|           1 |        John Doe | 50000.0 |  50 |\n|           2 |      Jane Smith | 65000.0 |  33 |\n|           3 |     Bob Johnson | 80000.0 |  42 |\n|           4 |     Alice Brown | 40000.0 |  21 |\n|           5 |    Peter Parker | 61000.0 |  55 |\n|           6 |      Jack Black | 73000.0 |  39 |\n|           7 | Nicole Williams | 44000.0 |  25 |\n|           8 |  Charlie Wilson | 72000.0 |  28 |\n+-------------+-----------------+---------+-----+\n```\n\nEasy to bucket on one or several attributes.\nResult can be displayed in\na [pivot table](https://github.com/squashql/squashql-showcase/blob/main/TUTORIAL.md#pivot-table)\nto enhance data visualization and help analysis.\n\n\u003cimg src=\"documentation/assets/bucketing-age-salary.png\" width=\"500\"\u003e\n\n👉 https://jsfiddle.net/azeq/r1xfqt89/\n\n[More](https://github.com/squashql/squashql/blob/main/documentation/QUERY.md#joining-on-virtual-created-on-the-fly-at-query-time)\n\n### Comparison or hierarchical measures\n\nMake calculations that are cumbersome or challenging in SQL easy to perform.\n\nHierarchical measures are multidimensional measures that are calculated based on the relationships between values in \ndifferent levels of a hierarchy. This allows for the calculation of percentages, ratios, and other comparisons that \nprovide insights into the distribution and change of data over time or across different levels of a hierarchy.\n\n#### Hierarchical / Parent-Child comparison\n\n💡 Compare aggregates and sub-aggregates computed at different levels of a lineage. A lineage is defined on-the-fly \nat query time. In below example, it is defined as `continent_name -\u003e country_name -\u003e city_name`.\n\n\u003cimg src=\"documentation/assets/parent-child-comp.png\" width=\"500\"\u003e\n\n👉 https://jsfiddle.net/azeq/31qs2jyt/\n\n#### Time-series comparison\n\n💡 Compare aggregates between time period like year, semester, quarter, month.\n\n\u003cimg src=\"documentation/assets/time-period-comp.png\" width=\"500\"\u003e\n\n👉 https://jsfiddle.net/azeq/dqebkp2x/\n\n[More](documentation/QUERY.md#complex-comparison)\n\n### Drilling across\n\nQuery two or more fact tables and stitch together the results on shared columns. SquashQL will fill aggregated values with \nnull for entries that are not compatible with the result they come from.\n\n```\nResult query 1                        Result query 2\n+-------------+---------------+       +-------------+-------------+-------------------+\n|     product | quantity sold |       |     product |      reason | quantity returned |\n+-------------+---------------+       +-------------+-------------+-------------------+\n| Grand Total |            54 |       | Grand Total | Grand Total |                 5 |\n|           A |            15 |       |           A |       Total |                 1 |\n|           B |            23 |       |           A |   defective |                 1 |\n|           C |            16 |       |           C |       Total |                 3 |\n+-------------+---------------+       |           C |    unwanted |                 3 |\n                                      |           D |       Total |                 1 |\n                                      |           D |    unwanted |                 1 |\n                                      +-------------+-------------+-------------------+\n```\n\nDrilling across result (with left join)\n\n\u003cimg src=\"documentation/assets/drilling-accross-minify.png\" width=\"500\"\u003e\n\n👉 https://jsfiddle.net/azeq/702gxqcb/\n\nN query results can be merged, `N \u003e= 2`.\n\n[More](documentation/DRILLING-ACROSS.md)\n\n### Query cache\n\nSquashQL provides an in-memory query cache to not re-execute queries already executed.\nCaching can be customized or deactivated.\n\n[More](documentation/CACHE.md)\n\n### Output format\n\nSquashQL supports several output format :\n\n* `text/plain`\n* `text/csv` (with `Content-Disposition` header allowing file download)\n* `application/json`\n\nThe default format for SquashQL is `application/json`.\nTo override this behavior and choose the selected output format, simply pass an `Accept` header when instantiating the querier :\n\n```javascript\nconst csvQuerier = new Querier(url, {\n    headers: {\n        'Accept': 'text/plain',\n    }\n});\n```\n\n## 🎓 Try SquashQL\n\nYou can try SquashQL directly from your web browser with [our showcase project](https://github.com/squashql/squashql-showcase/blob/main/TUTORIAL.md). No need to install anything!\n\n## 📕 Documentation\n\n- [Configuration](documentation/CONFIGURATION.md): learn how to connect SquashQL to your database.\n- [API tour](documentation/API.md): a quick introduction to the API.\n- [Typescript API Handbook](documentation/QUERY.md)\n- [Drilling across](documentation/DRILLING-ACROSS.md)\n- [Cache](documentation/CACHE.md)\n\n## 📚 Resources\n\n- [Typescript library](https://www.npmjs.com/package/@squashql/squashql-js) \n- [Tutorial](https://github.com/squashql/squashql-showcase/blob/main/TUTORIAL.md)\n\n## 🤝 Contributing\n\nWe are always thrilled to receive contributions: code, documentation, issues, or feedback.\n\n- Start by checking out the GitHub issues. These are a great place for newcomers to contribute.\n- Read our [Code of Conduct](CODE-OF-CONDUCT.md) to understand our community standards.\n- Read our [contributing guidelines](CONTRIBUTING.md) to understand how to contribute.\n- Create a fork to have your own copy of the repository where you can make changes. \n- Once you've made your changes and tested them, you can contribute by submitting a pull request.\n\nIf you can't find something you'd want to use or want to share your ideas, please open an issue or join our [discord server](https://discord.gg/p7dg2wEwFs).\n\n## 💬 Join Our Community\n\nWe welcome everyone to our community! Whether you're contributing code or just saying hello, we'd love to hear from you. \nJoin our [discord server](https://discord.gg/p7dg2wEwFs)!\n","funding_links":[],"categories":["Integrations","大数据"],"sub_categories":["Data Transfer and Synchronization"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquashql%2Fsquashql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquashql%2Fsquashql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquashql%2Fsquashql/lists"}