Spaces:
Sleeping
Sleeping
| import json | |
| import os | |
| SCHEMA_PROMPT = """You are a Text-to-SQL generator. Given a database schema and a natural language question, write a valid SQLite query that answers the question. Do not explain the query, just output the raw SQL. | |
| Database Schema: | |
| Table departments: | |
| - id: INTEGER (PRIMARY KEY) | |
| - name: TEXT (NOT NULL, UNIQUE, e.g., 'Sales', 'Engineering', etc.) | |
| - manager_id: INTEGER (references employees.id) | |
| Table employees: | |
| - id: INTEGER (PRIMARY KEY) | |
| - name: TEXT (NOT NULL) | |
| - department_id: INTEGER (references departments.id) | |
| - salary: INTEGER (NOT NULL) | |
| - hire_date: TEXT (NOT NULL, YYYY-MM-DD) | |
| - manager_id: INTEGER (references employees.id) | |
| Table products: | |
| - id: INTEGER (PRIMARY KEY) | |
| - name: TEXT (NOT NULL, UNIQUE, e.g., 'Enterprise CRM') | |
| - category: TEXT (NOT NULL, e.g., 'Software', 'Hardware', 'Cloud') | |
| - price: REAL (NOT NULL) | |
| Table sales: | |
| - id: INTEGER (PRIMARY KEY) | |
| - employee_id: INTEGER (NOT NULL, references employees.id) | |
| - product_id: INTEGER (NOT NULL, references products.id) | |
| - amount: REAL (NOT NULL) | |
| - quantity: INTEGER (NOT NULL) | |
| - sale_date: TEXT (NOT NULL, YYYY-MM-DD)""" | |
| # Training dataset pairs (50 high-quality pairs covering diverse SQL capabilities) | |
| TRAIN_DATA = [ | |
| # Basic select and filter | |
| ("List all employees and their salaries.", "SELECT name, salary FROM employees;"), | |
| ("Show all departments.", "SELECT * FROM departments;"), | |
| ("Find all products in the Software category.", "SELECT * FROM products WHERE category = 'Software';"), | |
| ("List products that cost more than 500 dollars.", "SELECT * FROM products WHERE price > 500;"), | |
| ("Find the salary of Bob Smith.", "SELECT salary FROM employees WHERE name = 'Bob Smith';"), | |
| ("Who was hired after January 1st, 2024?", "SELECT name, hire_date FROM employees WHERE hire_date > '2024-01-01';"), | |
| ("Show the name and price of the product with ID 3.", "SELECT name, price FROM products WHERE id = 3;"), | |
| ("Find the sales records for product ID 1.", "SELECT * FROM sales WHERE product_id = 1;"), | |
| ("List employees who earn less than 70000.", "SELECT name, salary FROM employees WHERE salary < 70000;"), | |
| ("Show the department name of department with ID 2.", "SELECT name FROM departments WHERE id = 2;"), | |
| # Aggregations & Group By | |
| ("What is the average salary of all employees?", "SELECT AVG(salary) AS average_salary FROM employees;"), | |
| ("How many employees are there in total?", "SELECT COUNT(*) AS total_employees FROM employees;"), | |
| ("What is the highest salary among employees?", "SELECT MAX(salary) AS max_salary FROM employees;"), | |
| ("What is the lowest salary among employees?", "SELECT MIN(salary) AS min_salary FROM employees;"), | |
| ("Find the total revenue generated from all sales.", "SELECT SUM(amount) AS total_revenue FROM sales;"), | |
| ("How many items were sold in total?", "SELECT SUM(quantity) AS total_quantity_sold FROM sales;"), | |
| ("What is the average price of a software product?", "SELECT AVG(price) AS avg_price FROM products WHERE category = 'Software';"), | |
| ("How many products are in each category?", "SELECT category, COUNT(*) AS product_count FROM products GROUP BY category;"), | |
| ("Find the average salary by department.", "SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id;"), | |
| ("Count the number of sales made by employee 6.", "SELECT COUNT(*) FROM sales WHERE employee_id = 6;"), | |
| # Joins | |
| ("List the names of employees alongside their department names.", "SELECT e.name, d.name AS department FROM employees e JOIN departments d ON e.department_id = d.id;"), | |
| ("Find the total quantity of CRM products sold.", "SELECT SUM(s.quantity) FROM sales s JOIN products p ON s.product_id = p.id WHERE p.name = 'Enterprise CRM';"), | |
| ("Show the manager's name for each department.", "SELECT d.name AS department, e.name AS manager FROM departments d JOIN employees e ON d.manager_id = e.id;"), | |
| ("Show the names of employees in the Engineering department.", "SELECT e.name FROM employees e JOIN departments d ON e.department_id = d.id WHERE d.name = 'Engineering';"), | |
| ("Who made a sale on Collaboration Tools?", "SELECT DISTINCT e.name FROM employees e JOIN sales s ON e.id = s.employee_id JOIN products p ON s.product_id = p.id WHERE p.name = 'Collaboration Tools';"), | |
| ("List all products sold by Alice Vance.", "SELECT DISTINCT p.name FROM products p JOIN sales s ON p.id = s.product_id JOIN employees e ON s.employee_id = e.id WHERE e.name = 'Alice Vance';"), | |
| ("Show all sales details, including employee name and product name.", "SELECT s.id, e.name AS employee_name, p.name AS product_name, s.amount, s.quantity, s.sale_date FROM sales s JOIN employees e ON s.employee_id = e.id JOIN products p ON s.product_id = p.id;"), | |
| ("Which employees generated sales of more than 1000 in a single transaction?", "SELECT DISTINCT e.name FROM employees e JOIN sales s ON e.id = s.employee_id WHERE s.amount > 1000;"), | |
| # Advanced aggregates & JOINs | |
| ("Find the total sales revenue generated by each employee in the Sales department.", "SELECT e.name, SUM(s.amount) AS total_revenue FROM employees e JOIN sales s ON e.id = s.employee_id JOIN departments d ON e.department_id = d.id WHERE d.name = 'Sales' GROUP BY e.name;"), | |
| ("Show the total amount of sales for each product, ordered by total revenue descending.", "SELECT p.name, SUM(s.amount) AS total_revenue FROM products p JOIN sales s ON p.id = s.product_id GROUP BY p.name ORDER BY total_revenue DESC;"), | |
| ("Which department has the highest average salary?", "SELECT d.name, AVG(e.salary) AS avg_salary FROM departments d JOIN employees e ON d.id = e.department_id GROUP d.name ORDER BY avg_salary DESC LIMIT 1;"), | |
| ("Find the employee who has made the most sales transactions.", "SELECT e.name, COUNT(s.id) AS transaction_count FROM employees e JOIN sales s ON e.id = s.employee_id GROUP BY e.name ORDER BY transaction_count DESC LIMIT 1;"), | |
| ("List departments that have an average employee salary greater than 80000.", "SELECT d.name, AVG(e.salary) AS avg_salary FROM departments d JOIN employees e ON d.id = e.department_id GROUP BY d.name HAVING avg_salary > 80000;"), | |
| # Dates | |
| ("Find all sales made in 2024.", "SELECT * FROM sales WHERE sale_date BETWEEN '2024-01-01' AND '2024-12-31';"), | |
| ("Find all sales made in the month of May 2024.", "SELECT * FROM sales WHERE sale_date BETWEEN '2024-05-01' AND '2024-05-31';"), | |
| ("List the names of employees hired in 2023.", "SELECT name FROM employees WHERE hire_date BETWEEN '2023-01-01' AND '2023-12-31';"), | |
| ("Show the sales revenue generated in the second half of 2024.", "SELECT SUM(amount) FROM sales WHERE sale_date BETWEEN '2024-07-01' AND '2024-12-31';"), | |
| # Subqueries & Complex | |
| ("List the products that have never been sold.", "SELECT p.name FROM products p LEFT JOIN sales s ON p.id = s.product_id WHERE s.id IS NULL;"), | |
| ("Which employees earn more than their manager?", "SELECT e.name FROM employees e JOIN employees m ON e.manager_id = m.id WHERE e.salary > m.salary;"), | |
| ("List all employees who report to Bob Smith.", "SELECT e.name FROM employees e JOIN employees m ON e.manager_id = m.id WHERE m.name = 'Bob Smith';"), | |
| ("Show the names of employees who have not made any sales.", "SELECT e.name FROM employees e LEFT JOIN sales s ON e.id = s.employee_id WHERE s.id IS NULL AND e.department_id = 1;"), | |
| ("Find products with a price higher than the average product price.", "SELECT name, price FROM products WHERE price > (SELECT AVG(price) FROM products);"), | |
| ("Which product had the highest single sales transaction amount?", "SELECT p.name, s.amount FROM products p JOIN sales s ON p.id = s.product_id ORDER BY s.amount DESC LIMIT 1;"), | |
| ("Show all employees who have the same manager as Grace Hopper.", "SELECT e.name FROM employees e WHERE e.manager_id = (SELECT manager_id FROM employees WHERE name = 'Grace Hopper') AND e.name != 'Grace Hopper';"), | |
| ("Find the total revenue by product category in 2025.", "SELECT p.category, SUM(s.amount) AS total_revenue FROM products p JOIN sales s ON p.id = s.product_id WHERE s.sale_date BETWEEN '2025-01-01' AND '2025-12-31' GROUP BY p.category;"), | |
| ("Find the department manager for Alice Vance's department.", "SELECT m.name FROM employees e JOIN departments d ON e.department_id = d.id JOIN employees m ON d.manager_id = m.id WHERE e.name = 'Alice Vance';"), | |
| ("Show the products whose total sales quantity exceeds 15 items.", "SELECT p.name, SUM(s.quantity) AS total_qty FROM products p JOIN sales s ON p.id = s.product_id GROUP BY p.name HAVING total_qty > 15;"), | |
| ("Find the most expensive product in the Hardware category.", "SELECT name, price FROM products WHERE category = 'Hardware' ORDER BY price DESC LIMIT 1;"), | |
| ("What is the average salary of employees hired in 2024?", "SELECT AVG(salary) FROM employees WHERE hire_date BETWEEN '2024-01-01' AND '2024-12-31';"), | |
| ("List all employees along with their manager's name.", "SELECT e.name AS employee, m.name AS manager FROM employees e LEFT JOIN employees m ON e.manager_id = m.id;") | |
| ] | |
| # Validation/Test dataset (12 high-quality out-of-sample pairs) | |
| TEST_DATA = [ | |
| ("List all employees in department 1.", "SELECT * FROM employees WHERE department_id = 1;"), | |
| ("Which software products cost less than 500 dollars?", "SELECT * FROM products WHERE category = 'Software' AND price < 500;"), | |
| ("How many departments do not have a manager?", "SELECT COUNT(*) FROM departments WHERE manager_id IS NULL;"), | |
| ("Find the total salary budget for the Engineering department.", "SELECT SUM(e.salary) FROM employees e JOIN departments d ON e.department_id = d.id WHERE d.name = 'Engineering';"), | |
| ("What is the total quantity of CRM products sold in 2024?", "SELECT SUM(s.quantity) FROM sales s JOIN products p ON s.product_id = p.id WHERE p.name = 'Enterprise CRM' AND s.sale_date BETWEEN '2024-01-01' AND '2024-12-31';"), | |
| ("Show the employee with the highest salary in department 2.", "SELECT name, salary FROM employees WHERE department_id = 2 ORDER BY salary DESC LIMIT 1;"), | |
| ("List employees who report directly to Alice Vance.", "SELECT e.name FROM employees e JOIN employees m ON e.manager_id = m.id WHERE m.name = 'Alice Vance';"), | |
| ("Find the average sale amount for employee ID 9.", "SELECT AVG(amount) FROM sales WHERE employee_id = 9;"), | |
| ("Find the total revenue generated from software category products.", "SELECT SUM(s.amount) FROM sales s JOIN products p ON s.product_id = p.id WHERE p.category = 'Software';"), | |
| ("Which product has the lowest price?", "SELECT name, price FROM products ORDER BY price ASC LIMIT 1;"), | |
| ("Find the employee who generated the highest total revenue across all sales.", "SELECT e.name, SUM(s.amount) AS total_revenue FROM employees e JOIN sales s ON e.id = s.employee_id GROUP BY e.name ORDER BY total_revenue DESC LIMIT 1;"), | |
| ("List products sold in November 2024.", "SELECT DISTINCT p.name FROM products p JOIN sales s ON p.id = s.product_id WHERE s.sale_date BETWEEN '2024-11-01' AND '2024-11-30';") | |
| ] | |
| def format_phi3_chat(question, sql_query): | |
| """ | |
| Format data in the standard Phi-3 Prompt Template: | |
| <|user|> | |
| [Schema + Instruction] | |
| Question: {question} | |
| <|end|> | |
| <|assistant|> | |
| {sql_query}<|end|> | |
| """ | |
| prompt = f"{SCHEMA_PROMPT}\n\nQuestion: {question}" | |
| # Return formatted chat message dictionary | |
| return { | |
| "messages": [ | |
| {"role": "user", "content": prompt}, | |
| {"role": "assistant", "content": sql_query} | |
| ] | |
| } | |
| def generate_datasets(output_dir="data"): | |
| os.makedirs(output_dir, exist_ok=True) | |
| train_formatted = [format_phi3_chat(q, sql) for q, sql in TRAIN_DATA] | |
| test_formatted = [format_phi3_chat(q, sql) for q, sql in TEST_DATA] | |
| # Save training | |
| train_path = os.path.join(output_dir, "train_dataset.jsonl") | |
| with open(train_path, "w", encoding="utf-8") as f: | |
| for item in train_formatted: | |
| f.write(json.dumps(item) + "\n") | |
| # Save test | |
| test_path = os.path.join(output_dir, "test_dataset.jsonl") | |
| with open(test_path, "w", encoding="utf-8") as f: | |
| for item in test_formatted: | |
| f.write(json.dumps(item) + "\n") | |
| print(f"Datasets generated successfully:") | |
| print(f" - Training dataset: {train_path} ({len(train_formatted)} records)") | |
| print(f" - Testing dataset: {test_path} ({len(test_formatted)} records)") | |
| if __name__ == "__main__": | |
| generate_datasets() | |