SQL for Mixed Case filter - sql

I was just wondering how you would search for any mix of case. For instance, I want to find all employees with the last name 'davies', but I want to be able to find any mix of case such as 'DavIes' or 'DAVies'. This is what I've tried.
SELECT LAST_NAME
FROM EMPLOYEES
WHERE DEPARTMENT_ID = (SELECT DEPARTMENT_ID
FROM EMPLOYEES
WHERE LAST_NAME = '[Dd][Aa][Vv][Ii][Ee][Ss]');

I would use UPPER or LOWER function and IN
SELECT LAST_NAME
FROM EMPLOYEES
WHERE DEPARTMENT_ID IN (
SELECT DEPARTMENT_ID
FROM EMPLOYEES
WHERE UPPER(LAST_NAME) = 'DAVIES'
);
Unfortunately it invalidates the index use.

Using UPPER
SELECT *
FROM EMPLOYEES
WHERE UPPER(LAST_NAME) = 'DAVIES'

Related

What is wrong with my Postgres statement?

SELECT first_name, last_name, manager_id
CASE manager_id
WHEN manager_id IS null THEN "pip"
End manager_id
FROM assgnssql.employees;
I am trying to select list of employees, but i know some employees do not have manager_id, for these employees without manager_id (null) i want the result to display "pip" while for the rest it displays original info.
The code you want is probably:
SELECT first_name, last_name, manager_id
(CASE WHEN manager_id IS null THEN 'pip' ELSE manager_id
END) as manager_id
FROM assgnssql.employees;
Or more simply:
SELECT first_name, last_name, manager_id
COALESCE(manager_id, 'pip') as manager_id
FROM assgnssql.employees;
The two significant issues are:
Your CASE syntax is messed up. Either you use comparisons or you have CASE <value>, but not both.
Strings are delimited by single quotes.

How do i change the result of an ORACLE select query for specific type of data?

I have a table named EMPLOYEES with columns EMPLOYEE_ID, NAME and DEPARTMENT_ID. I have to list all employees, changing the output of the attribute NAME to "---" if the department id is 10.
How can I do that? Thank you!
select
employee_id,
case when department_id = 10 then '---' else name end as name,
department_id
from employees;
Another solution using union all
select
employee_id, name, department_id
from employees WHERE department_id != 10
UNION all
select
employee_id, '---' name, department_id
from employees WHERE department_id = 10

Oracle SQL sub query

I have a practice that I should find the employees who earn more than average salary and works in the departments with employees whose last name contains the letter u
the select statement I have used was
SELECT employee_id,
last_name,
salary
FROM employees
WHERE salary > (SELECT AVG(salary)
FROM employees )
AND department_id IN(SELECT department_id
FROM employees
WHERE LOWER(last_name) LIKE '%u%')
Could anyone check this statement is suitable or not ?
thank you
That looks fine to me, assuming you mean the average salary across all departments in the database, and all employees (active or not) across all of time.
I would think you might be more interested in all active employees in this current financial year, for example.
You haven't provided the schema, so be careful to check for conditions like:
inactive departments
inactive / terminated employees
period you are interested in for comparing the salary
Your queries looks like it will work. You can rewrite it to remove all the sub-queries (that will require additional table/index scans) and just use analytic queries:
SELECT employee_id,
last_name,
salary
FROM (
SELECT employee_id,
last_name,
salary,
AVG( salary ) OVER () AS avg_salary,
COUNT( CASE WHEN LOWER( last_name ) LIKE '%u%' THEN 1 END )
OVER ( PARTITION BY department_id ) AS num_last_name_with_u
FROM employees
)
WHERE salary > avg_salary
AND num_last_name_with_u > 0;
db<>fiddle
My first Question are you getting the expected result ?
Let me break down your Query
SELECT department_id FROM employees WHERE LOWER(last_name)
Here you are selecting the department so it retrieve the department id, what is the need of selecting department Id when all you need employee_id with last name contains u so change it to employee_id instead of department_id
select avg(salary) over (partition by department_id order by employee_id)
So using partition by you must get the avg salary per department
SELECT employee_id,last_name,salary
FROM
employees
WHERE salary>(SELECT AVG(salary) OVER (PARTITION BY department_id)
FROM
employees )
AND employee_id IN
( SELECT employee_id
FROM
employees
WHERE LOWER(last_name) LIKE '%u%')
Let me know if you have any issues running it, any corrections to Query is appreciated

Unexpected result of a SQL query

Can anyone explain why this query:
SELECT employee_id, last_name, salary
FROM employees
WHERE department_id IN (SELECT department_id
FROM employees
WHERE last_name LIKE '%u%'
)
AND salary > (SELECT AVG(salary)
FROM employees);
returns way less rows than this nested one:
SELECT employee_id, last_name, salary
FROM employees
WHERE department_id IN (SELECT department_id
FROM employees
WHERE last_name LIKE '%u%'
AND salary > (SELECT AVG(salary)
FROM employees);
)
The first returns all employees who meet the following conditions:
The employee is in a department has a "u" employee.
The employee has a salary larger than the average.
The second returns all employees who meet these conditions:
The employee is in a department that has a "u" employee who has a salary larger than the average.
The two are very different conditions. I wouldn't expect them to return the same result set.
Also, whenever you have more than one table in a query, you should use table aliases that are abbreviations of the table name and you should qualify all column names.

SQL-Oracle: Difficulties in resolving basic problems, part2

Problem:
The HR department needs a query that prompts the user for an employee
last name. The query then displays the last name and hire date of any employee
in the same department as the employee whose name they supply(excluding that employee).
For example, if the user enters Zlotkey, find all employees who work with
Zlotkey (excluding Zlotkey).
I managed to do this so far, but i have no clue how to finish it. For now it shows me all employees after i write the last_name excluding it. Any suggestions please how to continue?
SELECT last_name, TO_CHAR(hire_date,'DD-MON-YYYY') AS "HIRE_DATE"
FROM employees
WHERE last_name <>ALL (SELECT '&last_name'
FROM employees)
AND department_id IN (SELECT department_id
???....
P.S: This problem is from the Oracle tutorials (Oracle Database 11g: SQL Fundamentals 1 of 1 (year 2009), Practice 7 , exercise 1 for people who already done this:).
Something like this?
SELECT last_name, TO_CHAR(hire_date,'DD-MON-YYYY') AS "HIRE_DATE"
FROM employees a
JOIN (Select department_id from employees where last_name = :surname) b on a.department_id = b.department_id
and last_name <> :surname
EDIT
The only problem with this type of solution is that if there are two people with the same surname in different departments, so it might be useful to maybe use something like an employee number as a filter instead of surname.
SELECT LAST_NAME, HIRE_DATE
FROM EMPLOYEES
WHERE DEPARTMENT_ID= (SELECT DEPARTMENT_ID
FROM EMPLOYEES
WHERE LAST_NAME LIKE '&NAME')
AND LAST_NAME <> '&NAME';