Finding user names with particular characters in their last name - sql

In Oracle SQL, I wish to find all user names,whose Last name contains some specific Characters like ('Z','X','D','F') Or contains Some Range of Characters from 'A-F'.
I tried this:
SELECT user_last_name
FROM userbase
WHERE user_last_name LIKE '%A%' OR user_last_name LIKE '%F%' .
So How can I go about it.
And I written facebook in question although its not directly related to it,because,its the example given by my sir.
UPDATE: I tried the above code,it works with so many OR's, but How can we define some range to search for like IN('Z','X','D','F') or IN ('A-F')

If you are using a recent version of Oracle, you should be able to use regular expressions
SQL> ed
Wrote file afiedt.buf
1 select first_name, last_name
2 from employees
3* where regexp_like( last_name, 'Z|X|D|[A-F]' )
SQL> /
FIRST_NAME LAST_NAME
-------------------- -------------------------
Ellen Abel
Sundar Ande
Mozhe Atkinson
David Austin
Hermann Baer
Shelli Baida
Amit Banda
Elizabeth Bates
Sarah Bell
David Bernstein
Laura Bissot
Harrison Bloom
Alexis Bull
Anthony Cabrio
Gerald Cambrault
Nanette Cambrault
John Chen
Kelly Chung
Karen Colmenares
Curtis Davies
Lex De Haan
Julia Dellinger
Jennifer Dilly
Louise Doran
Bruce Ernst
Alberto Errazuriz
Britney Everett
Daniel Faviet
Pat Fay
Kevin Feeney
Jean Fleaur
Tayler Fox
Adam Fripp
Samuel McCain
Allan McEwen
Donald OConnell
Eleni Zlotkey
37 rows selected.
If you want the search to be case-insensitive
SQL> ed
Wrote file afiedt.buf
1 select first_name, last_name
2 from employees
3* where regexp_like( last_name, 'Z|X|D|[A-F]', 'i' )
SQL> /
FIRST_NAME LAST_NAME
-------------------- -------------------------
Ellen Abel
Sundar Ande
Mozhe Atkinson
David Austin
Hermann Baer
Shelli Baida
Amit Banda
Elizabeth Bates
Sarah Bell
David Bernstein
Laura Bissot
Harrison Bloom
Alexis Bull
Anthony Cabrio
Gerald Cambrault
Nanette Cambrault
John Chen
Kelly Chung
Karen Colmenares
Curtis Davies
Lex De Haan
<<snip>>
Matthew Weiss
Jennifer Whalen
Eleni Zlotkey
93 rows selected.

You can use INSTR to test whether characters exist in your field, like so:
SELECT
user_last_name
FROM
userbase
WHERE 0 < INSTR(user_last_name,'A')
or 0 < INSTR(user_last_name,'B')
...repeat for each character you want to test for...

Related

Presenting Data uniformly between two different table presentations with SQL

Hello Everyone I have a problem…
Table 1 (sorted) is laid out like this:
User ID Producer ID Company Number
JWROSE 23401 234
KXPEAR 23903 239
LMWEEM 27902 279
KJMORS 18301 183
Table 2 (unsorted) looks like this:
Client Name City Company Number
Rajat Smith London JWROSE
Robert Singh Cleveland KXPEAR
Alberto Johnson New York City LMWEEM
Betty Lee Dallas KJMORS
Chase Galvez Houston 23401
Hassan Jackson Seattle 23903
Tooti Fruity Boise 27902
Joe Trump Tokyo 18301
Donald Biden Cairo 234
Mike Harris Rome 239
Kamala Pence Moscow 279
Adolf Washington Bangkok 183
Now… Table 1 has all of the User IDs and Producer IDs properly rowed with the Company Number.
I want to pull all the data and correctly sorted….
Client Name City User ID Producer ID Company Number
Rajat Smith London JWROSE 23401 234
Robert Singh Cleveland KXPEAR 23903 239
Alberto Johnson New York City LMWEEM 27902 279
Betty Lee Dallas KJMORS 18301 183
Chase Galvez Houston JWROSE 23401 234
Hassan Jackson Seattle KXPEAR 23903 239
Tooti Fruity Boise LMWEEM 27902 279
Joe Trump Tokyo KJMORS 18301 183
Donald Biden Cairo JWROSE 23401 234
Mike Harris Rome KXPEAR 23903 239
Kamala Pence Moscow LMWEEM 27902 279
Adolf Washington Bangkok KJMORS 18301 183
Query:
Select
b.client_name,
b.city.,
a.user_id,
a.producer_id,
a.company_number
From Table 1 A
Left Join Table 2 B On a.company….
And this is where I don’t know what do to….because both tables have all the same variables, but Company Number in Table 2 is mixed with User IDs and Producer IDs... however we know what company Number those ID's are associated to.
As I mention in the comments, and others do, the real problem is your design. "The fact that UserID is clearly a varchar, while the other 2 columns are an int really does not make this any better", and makes this not simple (and certainly not SARGable).
To get the data in the correct order, as well, you need a column to order it on which the data lacks. I have therefore added a pseudo column, MissingIDColumn, to represent this missing column you need to add to your data; which you can do when you fix the design:
SELECT T2.ClientName,
T2.City,
T1.UserID,
T1.ProducerID,
T1.CompanyNumber
FROM (VALUES('JWROSE',23401,234),
('KXPEAR',23903,239),
('LMWEEM',27902,279),
('KJMORS',18301,183))T1(UserID,ProducerID,CompanyNumber)
JOIN (VALUES(1,'Rajat Smith ','London ','JWROSE'),
(2,'Robert Singh ','Cleveland ','KXPEAR'),
(3,'Alberto Johnson ','New York City','LMWEEM'),
(4,'Betty Lee ','Dallas ','KJMORS'),
(5,'Chase Galvez ','Houston ','23401'),
(6,'Hassan Jackson ','Seattle ','23903'),
(7,'Tooti Fruity ','Boise ','27902'),
(8,'Joe Trump ','Tokyo ','18301'),
(9,'Donald Biden ','Cairo ','234'),
(10,'Mike Harris ','Rome ','239'),
(11,'Kamala Pence ','Moscow ','279'),
(12,'Adolf Washington','Bangkok ','183'))T2(MissingIDColumn,ClientName,City,CompanyNumber) ON T2.CompanyNumber IN (T1.UserID,CONVERT(varchar(6),T1.ProducerID),CONVERT(varchar(6),T1.CompanyNumber))
ORDER BY MissingIDColumn;

SQL Grouping of Salaries

I have a question to ask and I am supposed to create a query which shows:
MIN(lastname) MAX(firstname) SUM(salary) AVG(salary)
---------------------------------------------------------------
DAVIES TRINA 17500 3500
This was the query/queries I created:
SQL> SELECT MIN(LASTNAME), MAX(FIRSTNAME), SUM(SALARY), AVG(SALARY)
2 FROM EMPLOYEES
3 GROUP BY JOB_ID;
SQL> SELECT MIN(LASTNAME), MAX(FIRSTNAME), SUM(SALARY), AVG(SALARY)
2 FROM EMPLOYEES
3 GROUP BY JOB_ID, MANAGER_ID;
But I get multiple rows shown to me and in the part where DAVIES TRINA was shown the SUM and AVG salary is different and I am unsure how they were grouped.
MIN(LASTNAME) MAX(FIRSTNAME) SUM(SALARY) AVG(SALARY)
---------- ---------- ----------- -----------
ERNST DIANA 10200 5100
HIGGINS SHELLEY 12000 12000
GIETZ WILLIAM 8300 8300
MOURGOS KEVIN 5800 5800
WHALEN JENNIFER 4400 4400
DE HAAN NENA 34000 17000
ZLOTKEY ELENI 10500 10500
HARTSTEIN MICHAEL 13000 13000
KING STEVEN 24000 24000
ABEL KIMBERLEY 26600 8866.66667
FAY PAT 6000 6000
**DAVIES TRINA 11700 2925**
What am I doing wrong?
MORE INFO BELOW:
EMPLOYEE_ID FIRSTNAME LASTNAME JOB_ID SALARY MANAGER_ID DEPARTMENT_ID
100 STEVEN KING AD_PRES 24000 90
101 NENA KOCHAR AD_VP 17000 100 90
102 LEX DE HAAN AD_VP 17000 100 90
103 ALEXANDER HUNOLD IT_PROG 101 60
104 BRUCE ERNST IT_PROG 6000 102 60
107 DIANA LORENTZ IT_PROG 4200 103 60
124 KEVIN MOURGOS ST_MAN 5800 100 50
141 TRINA RAJS ST_CLERK 3500 124 50
142 CURTIS DAVIES ST_CLERK 3100 124 50
143 RANDALL MATOS ST_CLERK 2600 124 50
144 PETER VARGAS ST_CLERK 2500 124 50
EMPLOYEE_ID FIRSTNAME LASTNAME JOB_ID SALARY MANAGER_ID DEPARTMENT_ID
149 ELENI ZLOTKEY SA_MAN 10500 100 80
174 ELLEN ABEL SA_REP 11000 149 50
176 JONATHAN TAYLOR SA_REP 8600 149 80
178 KIMBERLEY GRANT SA_REP 7000 149
200 JENNIFER WHALEN AD_ASST 4400 101 10
201 MICHAEL HARTSTEIN MK_MAN 13000 100 20
202 PAT FAY MK_REP 6000 201 20
205 SHELLEY HIGGINS AC_MGR 12000 101 110
206 WILLIAM GIETZ AC_ACCOUNT 8300 205 110
If you provide the proper data that is, the data before running the query/queries and also tell why it should be 17500(sum) and 3500(avg) then you have more chances to get answers.
In the 1st query you are grouping based on JOB_ID. That means for all similar JOB_IDs (in case of SUM(SALARY)) it will select the the values of SALARY column and SUM the values for each different JOB_ID.
Example:
JOB_ID SALARY
1 200
2 300
1 150
2 100
3 270
If you run the following query:
Select JOB_ID,SUM(SALARY) FROM Table GROUP BY JOB_ID
Output:
JOB_ID SALARY
1 350
2 400
3 270

Confusion with the behavior of HAVING clause

I am not able to understand the behavior of the following query:
select max(avg(salary)) from employees
group by first_name
having avg(salary) >= max(salary);
It prints out the result as 17000. But if max(salary) is 24000 shouldn't there be empty result. If I replace "">="" with ">" it prints the result as NULL.
And if I replace ">=" with "<", then 13100 is printed in the result.
Below is the employees table:
TJ 2100
Steven 2200
Hazel 2200
James 2400
Ki 2400
Karen 2500
James 2500
Joshua 2500
Peter 2500
Martha 2500
Randall 2500
Guy 2600
Randall 2600
Donald 2600
Douglas 2600
Irene 2700
John 2700
Sigal 2800
Mozhe 2800
Girard 2800
Vance 2800
Shelli 2900
Michael 2900
Timothy 2900
Anthony 3000
Kevin 3000
Alex 3100
Curtis 3100
Jean 3100
Alana 3100
Julia 3200
Stephen 3200
Winston 3200
Samuel 3200
Laura 3300
Jason 3300
Julia 3400
Trenna 3500
Renske 3600
Jennife 3600
Kelly 3800
Britney 3900
Sarah 4000
Alexis 4100
Diana 4200
Nandita 4200
Jennife 4400
David 4800
Valli 4800
Kevin 5800
Bruce 6000
Pat 6000
Sundita 6100
Amit 6200
Charles 6200
Sundar 6400
Shanta 6500
Susan 6500
David 6800
Luis 6900
Oliver 7000
Sarath 7000
Kimbe 7000
Mattea 7200
Eliza 7300
William 7400
Nanette 7500
Louise 7500
Ismael 7700
Jose 7800
Payam 7900
Matthew 8000
Christ 8000
Lindsey 8000
John 8200
Adam 8200
William 8300
Jack 8400
Jonath 8600
Alyssa 8800
Alex 9000
Daniel 9000
Peter 9000
Allan 9000
Patrick 9500
Danie 9500
David 9500
Tayler 9600
Hermann 10000
Harris 10000
Janette 10000
Peter 10000
Clara 10500
Eleni 10500
Gerald 11000
Den 11000
Ellen 11000
Lisa 11500
Alberto 12000
Shelley 12008
Nancy 12008
Michael 13000
Karen 13500
John 14000
Lex 17000
Neena 17000
Steven 24000
You are doing Group By First_name, in your table,
For Neena, max(salary) = 17000 and avg(salary)=17000,
So, >= matches the condition in the query and 17000 is returned.
Where as replacing >= with > evaulated to NULL.
For Steven, Max(salary)=24000, AVG(salary)=(24000+2200)/2=13100
So replacing >= with < returns 13100
Note : Grouping by ColumnName here first_name plays the key role
here. All the aggregate functions in SELECT as well as having clause,
are applied per employee and not on the whole table.
If you want to compare an employee's mean salary (does this really make sense? Surely an employee only has one salary at a point in time?) then this might help
WITH
employees (first_name,salary)
AS
(SELECT 'TJ',2100 FROM dual UNION ALL
SELECT 'Steven',2200 FROM dual UNION ALL
SELECT 'Hazel',2200 FROM dual UNION ALL
SELECT 'James',2400 FROM dual UNION ALL
SELECT 'Ki',2400 FROM dual UNION ALL
SELECT 'Karen',2500 FROM dual UNION ALL
SELECT 'James',2500 FROM dual UNION ALL
SELECT 'Joshua',2500 FROM dual UNION ALL
SELECT 'Peter',2500 FROM dual UNION ALL
SELECT 'Martha',2500 FROM dual
)
SELECT
first_name
,mean_salary_all_emps
,AVG(salary)
FROM
(SELECT
first_name
,salary
,AVG(salary) OVER () mean_salary_all_emps
FROM
employees
)
WHERE 1=1
GROUP BY
first_name
,mean_salary_all_emps
HAVING AVG(salary) > mean_salary_all_emps
;

query on hr schema

I am new to SQL and am practicing on the HR schema available on Oracle 10g XE.
This is the question:
Write a query to select the name, job, and salary and department number of all employees except Sales Rep from department number 80.
My query is this:
select first_name||' '||last_name "Employee Name"
, job_id, salary, department_id
from employees
where not( job_id='SA_REP' and department_id=80 )
order by department_id;
Output:
Employee Name JOB_ID SALARY DEPARTMENT_ID
---------------------------------------------- ---------- ---------- -------------
Jennifer Whalen AD_ASST 4400 10
Michael Hartstein MK_MAN 13000 20
Pat Fay MK_REP 6000 20
Den Raphaely PU_MAN 11000 30
Alexander Khoo PU_CLERK 3100 30
Shelli Baida PU_CLERK 2900 30
Sigal Tobias PU_CLERK 2800 30
Guy Himuro PU_CLERK 2600 30
Karen Colmenares PU_CLERK 2500 30
Susan Mavris HR_REP 6500 40
Matthew Weiss ST_MAN 8000 50
Adam Fripp ST_MAN 8200 50
Payam Kaufling ST_MAN 7900 50
Shanta Vollman ST_MAN 6500 50
Kevin Mourgos ST_MAN 5800 50
Julia Nayer ST_CLERK 3200 50
Irene Mikkilineni ST_CLERK 2700 50
James Landry ST_CLERK 2400 50
Steven Markle ST_CLERK 2200 50
Laura Bissot ST_CLERK 3300 50
Mozhe Atkinson ST_CLERK 2800 50
James Marlow ST_CLERK 2500 50
TJ Olson ST_CLERK 2100 50
Jason Mallin ST_CLERK 3300 50
Michael Rogers ST_CLERK 2900 50
Ki Gee ST_CLERK 2400 50
Hazel Philtanker ST_CLERK 2200 50
Renske Ladwig ST_CLERK 3600 50
Stephen Stiles ST_CLERK 3200 50
John Seo ST_CLERK 2700 50
Joshua Patel ST_CLERK 2500 50
Trenna Rajs ST_CLERK 3500 50
Curtis Davies ST_CLERK 3100 50
Randall Matos ST_CLERK 2600 50
Peter Vargas ST_CLERK 2500 50
Winston Taylor SH_CLERK 3200 50
Jean Fleaur SH_CLERK 3100 50
Martha Sullivan SH_CLERK 2500 50
Girard Geoni SH_CLERK 2800 50
Nandita Sarchand SH_CLERK 4200 50
Alexis Bull SH_CLERK 4100 50
Julia Dellinger SH_CLERK 3400 50
Anthony Cabrio SH_CLERK 3000 50
Kelly Chung SH_CLERK 3800 50
Jennifer Dilly SH_CLERK 3600 50
Timothy Gates SH_CLERK 2900 50
Randall Perkins SH_CLERK 2500 50
Sarah Bell SH_CLERK 4000 50
Britney Everett SH_CLERK 3900 50
Samuel McCain SH_CLERK 3200 50
Vance Jones SH_CLERK 2800 50
Alana Walsh SH_CLERK 3100 50
Kevin Feeney SH_CLERK 3000 50
Donald OConnell SH_CLERK 2600 50
Douglas Grant SH_CLERK 2600 50
Alexander Hunold IT_PROG 9000 60
Bruce Ernst IT_PROG 6000 60
David Austin IT_PROG 4800 60
Valli Pataballa IT_PROG 4800 60
Diana Lorentz IT_PROG 4200 60
Hermann Baer PR_REP 10000 70
John Russell SA_MAN 14000 80
Karen Partners SA_MAN 13500 80
Alberto Errazuriz SA_MAN 12000 80
Gerald Cambrault SA_MAN 11000 80
Eleni Zlotkey SA_MAN 10500 80
Steven King AD_PRES 24000 90
Neena Kochhar AD_VP 17000 90
Lex De Haan AD_VP 17000 90
Nancy Greenberg FI_MGR 12000 100
Daniel Faviet FI_ACCOUNT 9000 100
John Chen FI_ACCOUNT 8200 100
Ismael Sciarra FI_ACCOUNT 7700 100
Luis Popp FI_ACCOUNT 6900 100
Jose Manuel Urman FI_ACCOUNT 7800 100
Shelley Higgins AC_MGR 12000 110
William Gietz AC_ACCOUNT 8300 110
77 rows selected.
I am not however getting the desired output,as the output is not displaying this row:
Employee Name JOB_ID SALARY DEPARTMENT_ID
---------------------------------------------- ---------- ---------- -------------
Kimberely Grant SA_REP 7000
This record does not have a department number, but it should also be displayed in the output along with the other 77 rows. Can anyone please point out where i am going wrong with the query?
So the goal is to get a list of all employees except those who are sales reps and in department 80? That is, you still want employees in department 80 (as well as all other departments) unless they are sales reps, and sales reps unless they are in department 80?
In Oracle, the comparison of a NULL value with anything else returns NULL rather than TRUE or FALSE. So you'll want to either: (a) add an explicit IS NULL condition (or IS NOT NULL, depending on your query parameters) or (b) use the COALESCE() (or NVL()) function. Something like this:
SELECT first_name || ' ' || last_name "Employee Name"
, job_id, salary, department_id
FROM employees
WHERE job_id != 'SA_REP'
OR department_id IS NULL
OR department_id != 80
ORDER BY department_id;
or:
SELECT first_name || ' ' || last_name "Employee Name"
, job_id, salary, department_id
FROM employees
WHERE job_id != 'SA_REP'
OR COALESCE(department_id, 0) != 80
ORDER BY department_id;
Thanks to #DavidFaber for confirming my original thought. The not that you have in your where clause isn't playing nice with the department_id = 80 portion, because of the empty value for Kimbereley Grant in department_id. Basically, the "not (job_id='SA_REP' and department_id=80)" becomes "not job_id='SA_REP' or not department_id=80", hence "job_id != 'SA_REP' or department_id != 80".
Kimberely Grant fails the first check (her job_id is in fact SA_REP) and the second check should result in essentially, "Unknown" (her department_id is not 80, but it's not not 80 either, it's NULL). As a result, you have false or "Unknown" which becomes false.
The fix is what #Ponder suggested. Add a null check on department_id:
not (job_id='SA_REP' and department_id=80 and department_id is not null)
which is equivalent to:
not (job_id='SA_REP' and department_id=80) or department_id is null
Thanks every one. I am able to get the required output now with this query:
SELECT first_name || ' ' || last_name "Employee Name"
, job_id, salary, department_id
FROM employees
WHERE job_id != 'SA_REP'
OR department_id IS NULL
OR department_id != 80
ORDER BY department_id;
Many Thanks again.Cheers.

Formatting error while creating report using Shell Script

HI all I am fairly new to Shell Scripting .. I was testing a sample report in which I was trying to spool the output of sql query embedded in shell script. here is my code
#!/bin/sh
ORACLE_ACCESS=hr/hr#xe
# Report file location
FILE_LOCATION=/home/$USER/Documents/loaddata/
#File Name
FILE_NAME=Report_`date +%y%m%d`.csv
sqlplus -s $ORACLE_ACCESS <<EOF 2>log.txt
set serveroutout on
set echo off
set first_name format A120
spool ${FILE_LOCATION}${FILE_NAME}
select first_name,last_name
from employees;
exit;
EOF
sql_error=$?
if [$sql_error !=0]; then
echo "Error"
exit 1
fi
However I am getting a pretty badly formatted output.
below is the sample
FIRST_NAME LAST_NAME
Ellen Abel
Sundar Ande
Mozhe Atkinson
David Austin
Hermann Baer
Shelli Baida
Amit Banda
Elizabeth Bates
Sarah Bell
David Bernstein
Laura Bissot
FIRST_NAME LAST_NAME
Harrison Bloom
Alexis Bull
Anthony Cabrio
Gerald Cambrault
Nanette Cambrault
John Chen
Kelly Chung
Karen Colmenares
My intended output should look something like below
First_name Last_name
Atlas Levine
John Doe
can somebody help?
Is your intended output like
First_name Last_name
Atlas Levine
John Doe
If so you can use something like set pagesize 10000 or something large so that the header doesnt get repeated. If you want to skip the header you can just set it to 0 You can refer the answers and links in Formatting output of queries in SQLPlus along with many other similar questions