diff --git a/CHANGELOG.md b/CHANGELOG.md
index ccd92e5..9af5d96 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- [#18](https://github.com/green-code-initiative/ecoCode-javascript/pull/18) add rule `@ecocode/limit-db-query-results`
- [#14](https://github.com/green-code-initiative/ecoCode-javascript/pull/14) Create SonarQube plugin
- [#12](https://github.com/green-code-initiative/ecoCode-javascript/issues/12) Pack ESLint plugin into SonarQube plugin
- [#16](https://github.com/green-code-initiative/ecoCode-javascript/pull/16) Use centralized rules specifications
diff --git a/eslint-plugin/README.md b/eslint-plugin/README.md
index c6188f2..c8dd434 100644
--- a/eslint-plugin/README.md
+++ b/eslint-plugin/README.md
@@ -59,6 +59,7 @@ Add `@ecocode` to the `plugins` section of your `.eslintrc`, followed by rules c
| Name | Description | ⚠️ |
| :------------------------------------------------------------------------------------- | :--------------------------------------------------------- | :- |
| [avoid-high-accuracy-geolocation](docs/rules/avoid-high-accuracy-geolocation.md) | Avoid using high accuracy geolocation in web applications. | ✅ |
+| [limit-db-query-results](docs/rules/limit-db-query-results.md) | Should limit the number of returns for a SQL query | ✅ |
| [no-import-all-from-library](docs/rules/no-import-all-from-library.md) | Should not import all from library | ✅ |
| [no-multiple-access-dom-element](docs/rules/no-multiple-access-dom-element.md) | Disallow multiple access of same DOM element. | ✅ |
| [no-multiple-style-changes](docs/rules/no-multiple-style-changes.md) | Disallow multiple style changes at once. | ✅ |
diff --git a/eslint-plugin/docs/rules/limit-db-query-results.md b/eslint-plugin/docs/rules/limit-db-query-results.md
new file mode 100644
index 0000000..4626876
--- /dev/null
+++ b/eslint-plugin/docs/rules/limit-db-query-results.md
@@ -0,0 +1,23 @@
+# Should limit the number of returns for a SQL query (`@ecocode/limit-db-query-results`)
+
+⚠️ This rule _warns_ in the ✅ `recommended` config.
+
+
+
+## Rule Details
+
+This rule aims at reducing CPU consumption by limiting the number of returns for a single SQL query.
+
+## Examples
+
+Examples of **non compliant** code for this rule:
+
+```js
+const query = "SELECT * FROM clients";
+```
+
+Examples of **compliant** code for this rule:
+
+```js
+const query = "SELECT columns FROM table_name FETCH FIRST number ROWS ONLY";
+```
diff --git a/eslint-plugin/lib/rules/limit-db-query-results.js b/eslint-plugin/lib/rules/limit-db-query-results.js
new file mode 100644
index 0000000..9a7b2e7
--- /dev/null
+++ b/eslint-plugin/lib/rules/limit-db-query-results.js
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2023 Green Code Initiative
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+"use strict";
+
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+ meta: {
+ type: "suggestion",
+ docs: {
+ description: "Should limit the number of returns for a SQL query",
+ category: "eco-design",
+ recommended: "warn",
+ },
+ messages: {
+ LimitTheNumberOfReturns:
+ "Try and limit the number of data returned for a single query (by using the LIMIT keyword for example)",
+ },
+ schema: [],
+ },
+ create(context) {
+ //list of limiting clauses to check against
+ const limitingClauses = ["LIMIT", "TOP", "ROW_NUMBER", "FETCH FIRST"];
+ return {
+ Literal: function (node) {
+ if (typeof node.value == "string") {
+ const query = node.value.toUpperCase();
+ if (
+ query.includes("SELECT") &&
+ query.includes("FROM") &&
+ !limitingClauses.some((clause) => query.includes(clause))
+ ) {
+ context.report({
+ node: node,
+ messageId: "LimitTheNumberOfReturns",
+ });
+ }
+ }
+ },
+ };
+ },
+};
diff --git a/eslint-plugin/tests/lib/rules/limit-db-query-results.js b/eslint-plugin/tests/lib/rules/limit-db-query-results.js
new file mode 100644
index 0000000..6658c42
--- /dev/null
+++ b/eslint-plugin/tests/lib/rules/limit-db-query-results.js
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2023 Green Code Initiative
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+"use strict";
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require("../../../lib/rules/limit-db-query-results"),
+ RuleTester = require("eslint").RuleTester;
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({
+ parserOptions: {
+ ecmaVersion: 6,
+ sourceType: "module",
+ },
+});
+const expectedError = {
+ messageId: "LimitTheNumberOfReturns",
+ type: "Literal",
+};
+
+ruleTester.run("limit-db-query-results", rule, {
+ valid: [
+ `
+ const query = "SELECT * FROM customers LIMIT 10;";
+ `,
+ `
+ const query = "SELECT TOP 5 * FROM products;";
+ `,
+ `
+ const query = "SELECT * FROM orders FETCH FIRST 20 ROWS ONLY;";
+ `,
+ `
+ const query = "WITH numbered_customers AS (SELECT *, ROW_NUMBER() OVER (ORDER BY customer_id) AS row_num FROM customers) SELECT * FROM numbered_customers WHERE row_num <= 50;";
+ `,
+ ],
+
+ invalid: [
+ {
+ code: `const query = "SELECT * FROM bikes;";`,
+ errors: [expectedError],
+ },
+ ],
+});