Skip to content

Branch 1 #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# 🏢 Primary Department for Each Employee - LeetCode 1789

## 📌 Problem Statement
You are given a table **Employee** that contains the following columns:

- **employee_id**: The ID of the employee.
- **department_id**: The ID of the department to which the employee belongs.
- **primary_flag**: An ENUM ('Y', 'N').
- If `primary_flag` is `'Y'`, then the department is the primary department for that employee.
- If `primary_flag` is `'N'`, then the department is not primary.

**Note:**
- An employee can belong to multiple departments. When an employee joins multiple departments, they decide which one is their primary (set to `'Y'`).
- If an employee belongs to only one department, then their `primary_flag` is `'N'`, but that department is still considered their primary department.

Your task is to **report all employees with their primary department**.
For employees who belong to only one department, report that department.

Return the result table in **any order**.

---

## 📊 Table Structure

### **Employee Table**
| Column Name | Type |
| ------------- | ------- |
| employee_id | int |
| department_id | int |
| primary_flag | varchar |

- `(employee_id, department_id)` is the **primary key** for this table.

---

## 📊 Example 1:

### **Input:**
#### **Employee Table**
| employee_id | department_id | primary_flag |
| ----------- | ------------- | ------------ |
| 1 | 1 | N |
| 2 | 1 | Y |
| 2 | 2 | N |
| 3 | 3 | N |
| 4 | 2 | N |
| 4 | 3 | Y |
| 4 | 4 | N |

### **Output:**
| employee_id | department_id |
| ----------- | ------------- |
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
| 4 | 3 |

### **Explanation:**
- **Employee 1** belongs to only one department (1), so department 1 is their primary.
- **Employee 2** belongs to departments 1 and 2. The row with `primary_flag = 'Y'` indicates that department 1 is their primary.
- **Employee 3** belongs only to department 3.
- **Employee 4** belongs to departments 2, 3, and 4. The row with `primary_flag = 'Y'` indicates that department 3 is their primary.

---

## 🖥 SQL Solution

### ✅ **Approach:**
- **Step 1:** For employees who have `primary_flag = 'Y'`, choose those rows.
- **Step 2:** For employees who belong to only one department, return that row.
- Combine the results using `UNION DISTINCT`.

```sql
SELECT employee_id, department_id
FROM Employee
WHERE primary_flag = 'Y'
UNION DISTINCT
SELECT employee_id, department_id
FROM Employee
GROUP BY employee_id
HAVING COUNT(*) = 1;
```

---

## 🐍 Python (Pandas) Solution

### ✅ **Approach:**
1. **Group** the DataFrame by `employee_id`.
2. For each group:
- If any row has `primary_flag == 'Y'`, choose the first such row.
- Otherwise (i.e., employee belongs to only one department), choose that row.
3. Return the resulting DataFrame with only `employee_id` and `department_id`.

```python
import pandas as pd

def primary_department(employees: pd.DataFrame) -> pd.DataFrame:
def select_primary(group):
# If there's any row with primary_flag 'Y', choose the first one
if (group['primary_flag'] == 'Y').any():
return group[group['primary_flag'] == 'Y'].iloc[0]
else:
# For employees with only one department
return group.iloc[0]

result = employees.groupby('employee_id').apply(select_primary).reset_index(drop=True)
return result[['employee_id', 'department_id']]
```

---

## 📁 File Structure
```
📂 Primary-Department
│── README.md
│── solution.sql
│── solution_pandas.py
│── test_cases.sql
│── sample_data.csv
```

---

## 🔗 Useful Links
- 📖 [LeetCode Problem](https://leetcode.com/problems/primary-department-for-each-employee/)
- 🔍 [MySQL UNION Operator](https://www.w3schools.com/sql/sql_union.asp)
- 🐍 [Pandas GroupBy Documentation](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html)
184 changes: 184 additions & 0 deletions LeetCode SQL 50 Solution/1907. Count Salary Categories/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# 💰 Count Salary Categories - LeetCode 907

## 📌 Problem Statement
You are given a table **Accounts** that contains information about bank accounts, including their monthly income.
Your task is to calculate the number of bank accounts in each salary category.

The salary categories are defined as follows:
- **"Low Salary"**: Salaries strictly less than \$20,000.
- **"Average Salary"**: Salaries in the inclusive range [\$20,000, \$50,000].
- **"High Salary"**: Salaries strictly greater than \$50,000.

The result table must contain **all three categories**. If there are no accounts in a category, return 0.

Return the result in **any order**.

---

## 📊 Table Structure

### **Accounts Table**
| Column Name | Type |
| ----------- | ---- |
| account_id | int |
| income | int |

- `account_id` is the **primary key** for this table.
- Each row contains the monthly income for one bank account.

---

## 📊 Example 1:

### **Input:**
#### **Accounts Table**
| account_id | income |
| ---------- | ------ |
| 3 | 108939 |
| 2 | 12747 |
| 8 | 87709 |
| 6 | 91796 |

### **Output:**
| category | accounts_count |
| -------------- | -------------- |
| Low Salary | 1 |
| Average Salary | 0 |
| High Salary | 3 |

### **Explanation:**
- **Low Salary**: Account with income 12747.
- **Average Salary**: No accounts have an income in the range [20000, 50000].
- **High Salary**: Accounts with incomes 108939, 87709, and 91796.

---

## 🖥 SQL Solution

### ✅ **Approach:**
1. **CTE "S"**: Create a static table with the three salary categories.
```sql
WITH S AS (
SELECT 'Low Salary' AS category
UNION
SELECT 'Average Salary'
UNION
SELECT 'High Salary'
),
```
- This defines the three salary categories to ensure every category appears in the final result.

2. **CTE "T"**: Categorize each account from the **Accounts** table using a `CASE` statement and count the number of accounts in each category.
```sql
T AS (
SELECT
CASE
WHEN income < 20000 THEN 'Low Salary'
WHEN income > 50000 THEN 'High Salary'
ELSE 'Average Salary'
END AS category,
COUNT(1) AS accounts_count
FROM Accounts
GROUP BY 1
)
```
- The `CASE` statement assigns a salary category based on the income.
- `COUNT(1)` counts the number of accounts in each category.

3. **Final SELECT with LEFT JOIN**: Combine the static category table `S` with the computed counts from `T` to ensure every category is included, using `IFNULL` to convert any missing count to 0.
```sql
SELECT S.category, IFNULL(T.accounts_count, 0) AS accounts_count
FROM S
LEFT JOIN T USING (category);
```

### ✅ **Complete SQL Query:**
```sql
WITH S AS (
SELECT 'Low Salary' AS category
UNION
SELECT 'Average Salary'
UNION
SELECT 'High Salary'
),
T AS (
SELECT
CASE
WHEN income < 20000 THEN 'Low Salary'
WHEN income > 50000 THEN 'High Salary'
ELSE 'Average Salary'
END AS category,
COUNT(1) AS accounts_count
FROM Accounts
GROUP BY 1
)
SELECT S.category, IFNULL(T.accounts_count, 0) AS accounts_count
FROM S
LEFT JOIN T USING (category);
```

---

## 🐍 Python (Pandas) Solution

### ✅ **Approach:**
1. **Categorize Accounts**: Create a new column `category` in the DataFrame by applying the salary conditions.
2. **Group and Count**: Group by the `category` column and count the number of accounts.
3. **Merge with Static Categories**: Ensure all three salary categories appear by merging with a predefined DataFrame that contains all categories, filling missing counts with 0.

```python
import pandas as pd

def count_salary_categories(accounts: pd.DataFrame) -> pd.DataFrame:
# Define the salary categorization function
def categorize(income):
if income < 20000:
return 'Low Salary'
elif income > 50000:
return 'High Salary'
else:
return 'Average Salary'

# Apply categorization
accounts['category'] = accounts['income'].apply(categorize)

# Count accounts in each category
counts = accounts.groupby('category').size().reset_index(name='accounts_count')

# Define static categories DataFrame
categories = pd.DataFrame({
'category': ['Low Salary', 'Average Salary', 'High Salary']
})

# Merge to ensure all categories are present, fill missing values with 0
result = categories.merge(counts, on='category', how='left')
result['accounts_count'] = result['accounts_count'].fillna(0).astype(int)

return result

# Example usage:
# df = pd.read_csv("sample_accounts.csv")
# print(count_salary_categories(df))
```

---

## 📁 File Structure
```
📂 Count-Salary-Categories
│── README.md
│── solution.sql
│── solution_pandas.py
│── test_cases.sql
│── sample_accounts.csv
```

---

## 🔗 Useful Links
- 📖 [LeetCode Problem](https://leetcode.com/problems/count-salary-categories/)
- 📝 [MySQL WITH Clause (CTE)](https://www.w3schools.com/sql/sql_with.asp)
- 🔍 [MySQL IFNULL Function](https://www.w3schools.com/sql/func_mysql_ifnull.asp)
- 🐍 [Pandas GroupBy Documentation](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html)
```

Loading