I want to find duplicates based on the first three characters of the surname, is there a way a to do that on SQL? I can compare the whole name, but how to do we compare the first few characters?
Below are my tables
custid forename surname dateofbirth
----------------------------------------
1 David John 16-09-1985
2 David Jon 16-09-1985
3 Sarah Smith 10-08-2015
4 Peter Proca 11-06-2011
5 Peter Proka 11-06-2011
This is my query that I am currently running to compare
SELECT
y.id, y.forename, y.surname
FROM
customers y
INNER JOIN
(SELECT
forename, surname, COUNT(*) AS CountOf
FROM customers
GROUP BY forename, surname
HAVING COUNT(*) > 1) dt ON y.forename = dt.forename
You can use left():
select c.*
from (select c.*, count(*) over (partition by left(surname, 3)) as cnt
from customers c
) c
order by surname;
You can include the forename as well in the partition by if you mean forename and first three letters of surname.
You can use exists as follows:
select t.* from t
Where exists
(select 1 from t tt
Where left(t.surname, 3) = left(tt.surname, 3) and t.custid <> tt.custid
)
order by t.surname;
I am making a select that returns me a table likes this
Name surname
Jhon a
Jhon b
Jhon c
Joe a
Joe b
Joe c
But what I need to get is just one occurrence of Jhon and one of Joe with one of the surnames.
I can only have one Jhon with one surname and one Joe with a surname..
I cannot make an order by because I need to select Name and surname.. Also if I use distinct I will have all Jhons and Joes..
Can you help me?
You can just use aggregation:
select name, max(surname) as surname
from table t
group by name;
You can also do something similar with analytic functions:
select t.name, t.surname
from (select t.*, row_number() over (partition by name order by name) as seqnum
from table t
) t
where seqnum = 1;
This is particularly useful if you want to get more than one column from the same row.
I have a table called names, and I want to select 2 names after being count(*) as uniq, and then another 2 names just from the entire sample pool.
firstname
John
John
Jessica
Mary
Jessica
John
David
Walter
So the first 2 names would select from a pool of John, Jessica, and Mary etc giving them equal chances of being selected, while the second 2 names will select from the entire pool, so obvious bias will be given to John and Jessica with multiple rows.
I'm sure there's a way to do this but I just can't figure it out. I want to do something like
SELECT uniq.firstname
FROM (SELECT firstname, count(*) as count from names GROUP BY firstname) uniq
limit 2
AND
SELECT firstname
FROM (SELECT firstname from names) limit 2
Is this possible? Appreciate any pointers.
I think you are close but you need some randomness for the sampling:
(SELECT uniq.firstname
FROM (SELECT firstname, count(*) as count from names GROUP BY firstname) uniq
ORDER BY rand()
limit 2
)
UNION ALL
(SELECT firstname
FROM from names
ORDER BY rand()
limit 2
)
As mentioned here you can use RAND or similar functions to achieve it depending on the database.
MySQL:
SELECT firstname
FROM (SELECT firstname, COUNT(*) as count FROM names GROUP BY firstname)
ORDER BY RAND()
LIMIT 2
PostgreSQL:
SELECT firstname
FROM (SELECT firstname, COUNT(*) as count FROM names GROUP BY firstname)
ORDER BY RANDOM()
LIMIT 2
Microsoft SQL Server:
SELECT TOP 2 firstname
FROM (SELECT firstname, COUNT(*) as count FROM names GROUP BY firstname)
ORDER BY NEWID()
IBM DB2:
SELECT firstname , RAND() as IDX
FROM (SELECT firstname, COUNT(*) as count FROM names GROUP BY firstname)
ORDER BY IDX FETCH FIRST 2 ROWS ONLY
Oracle:
SELECT firstname
FROM(SELECT firstname, COUNT(*) as count FROM names GROUP BY firstname ORDER BY dbms_random.value )
WHERE rownum in (1,2)
Follow the similar approach for selecting from entire pool
Say I've got the following data back from a SQL query:
Lastname Firstname Age
Anderson Jane 28
Anderson Lisa 22
Anderson Jack 37
If I want to know the age of the oldest person with the last name Anderson, I can select MAX(Age) and GROUP BY Lastname. But I also want to know the first name of that oldest person. How can I make sure that, when the Firstname values are collapsed into one row by the GROUP BY, I get the Firstname value from the same row where I got the max age?
For those RDBMS that support it (e.g., SQL Server 2005+), you can use a window function:
select t.Lastname, t.Firstname, t.Age
from (select Lastname, Firstname, Age,
row_number() over (partition by Lastname order by Age desc) as RowNum
from YourTable
) t
where t.RowNum = 1
For others, you'd need a subquery on Lastname and a join to get Firstname:
select yt.Lastname, yt.Firstname, yt.Age
from YourTable yt
inner join (select LastName, max(Age) as MaxAge
from YourTable
group by LastName) q
on yt.Lastname = q.Lastname
and yt.Age = q.MaxAge
You have to join back to the table from your grouped results - i.e. create a view or a nested query to contain the group by.
The main thing you need to watch out for whatever your approach is that there might be more than 1 firstname with the same age for a given lastname.
This query will return just 1 row, but if your data set had more than one 'Anderson' aged 37, it could return either one:
select firstname, age
from yourtable
where lastname = 'Anderson'
order by age desc limit 1
I want to find 2nd, 3rd, ... nth maximum value of a column.
Consider the following Employee table with a single column for salary.
+------+
| Sal |
+------+
| 3500 |
| 2500 |
| 2500 |
| 5500 |
| 7500 |
+------+
The following query will return the Nth Maximum element.
select SAL from EMPLOYEE E1 where
(N - 1) = (select count(distinct(SAL))
from EMPLOYEE E2
where E2.SAL > E1.SAL )
For eg. when the second maximum value is required,
select SAL from EMPLOYEE E1 where
(2 - 1) = (select count(distinct(SAL))
from EMPLOYEE E2
where E2.SAL > E1.SAL )
+------+
| Sal |
+------+
| 5500 |
+------+
You didn't specify which database, on MySQL you can do
SELECT column FROM table ORDER BY column DESC LIMIT 7,10;
Would skip the first 7, and then get you the next ten highest.
You could sort the column into descending format and then just obtain the value from the nth row.
EDIT::
Updated as per comment request. WARNING completely untested!
SELECT DOB FROM (SELECT DOB FROM USERS ORDER BY DOB DESC) WHERE ROWID = 6
Something like the above should work for Oracle ... you might have to get the syntax right first!
Again you may need to fix for your database, but if you want the top 2nd value in a dataset that potentially has the value duplicated, you'll want to do a group as well:
SELECT column
FROM table
WHERE column IS NOT NULL
GROUP BY column
ORDER BY column DESC
LIMIT 5 OFFSET 2;
Would skip the first two, and then will get you the next five highest.
Pure SQL (note: I would recommend using SQL features specific to your DBMS since it will be likely more efficient). This will get you the n+1th largest value (to get smallest, flip the <). If you have duplicates, make it COUNT( DISTINCT VALUE )..
select id from table order by id desc limit 4 ;
+------+
| id |
+------+
| 2211 |
| 2210 |
| 2209 |
| 2208 |
+------+
SELECT yourvalue
FROM yourtable t1
WHERE EXISTS( SELECT COUNT(*)
FROM yourtable t2
WHERE t1.id <> t2.id
AND t1.yourvalue < t2.yourvalue
HAVING COUNT(*) = 3 )
+------+
| id |
+------+
| 2208 |
+------+
(Table Name=Student, Column Name= mark)
select * from(select row_number() over (order by mark desc) as t,mark from student group by mark) as td where t=4
You can find the nth largest value of column by using the following query:
SELECT * FROM TableName a WHERE
n = (SELECT count(DISTINCT(b.ColumnName))
FROM TableName b WHERE a.ColumnName <=b.ColumnName);
select column_name from table_name
order by column_name desc limit n-1,1;
where n = 1, 2, 3,....nth max value.
Here's a method for Oracle. This example gets the 9th highest value. Simply replace the 9 with a bind variable containing the position you are looking for.
select created from (
select created from (
select created from user_objects
order by created desc
)
where rownum <= 9
order by created asc
)
where rownum = 1
If you wanted the nth unique value, you would add DISTINCT on the innermost query block.
Just dug out this question when looking for the answer myself, and this seems to work for SQL Server 2005 (derived from Blorgbeard's solution):
SELECT MIN(q.col1) FROM (
SELECT
DISTINCT TOP n col1
FROM myTable
ORDER BY col1 DESC
) q;
Effectively, that is a SELECT MIN(q.someCol) FROM someTable q, with the top n of the table retrieved by the SELECT DISTINCT... query.
Select max(sal)
from table t1
where N (select max(sal)
from table t2
where t2.sal > t1.sal)
To find the Nth max sal.
SELECT * FROM tablename
WHERE columnname<(select max(columnname) from tablename)
order by columnname desc limit 1
This is query for getting nth Highest from colomn put n=0 for second highest and n= 1 for 3rd highest and so on...
SELECT * FROM TableName
WHERE ColomnName<(select max(ColomnName) from TableName)-n order by ColomnName desc limit 1;
Simple SQL Query to get the employee detail who has Nth MAX Salary in the table Employee.
sql> select * from Employee order by salary desc LIMIT 1 OFFSET <N - 1>;
Consider table structure as:
Employee (
id [int primary key auto_increment],
name [varchar(30)],
salary [int] );
Example:
If you need 3rd MAX salary in the above table then, query will be:
sql> select * from Employee order by salary desc LIMIT 1 OFFSET 2;
Similarly:
If you need 8th MAX salary in the above table then, query will be:
sql> select * from Employee order by salary desc LIMIT 1 OFFSET 7;
NOTE:
When you have to get the Nth MAX value you should give the OFFSET as (N - 1).
Like this you can do same kind of operation in case of salary in ascending order.
mysql query:
suppose i want to find out nth max salary form employee table
select salary
form employee
order by salary desc
limit n-1,1 ;
In SQL Server, just do:
select distinct top n+1 column from table order by column desc
And then throw away the first value, if you don't need it.
for SQL 2005:
SELECT col1 from
(select col1, dense_rank(col1) over (order by col1 desc) ranking
from t1) subq where ranking between 2 and #n
MySQL:
select distinct(salary) from employee order by salary desc limit (n-1), 1;
Answer :
top second:
select * from (select * from deletetable where rownum <=2 order by rownum desc) where rownum <=1
select sal,ename from emp e where
2=(select count(distinct sal) from emp where e.sal<=emp.sal) or
3=(select count(distinct sal) from emp where e.sal<=emp.sal) or
4=(select count(distinct sal) from emp where e.sal<=emp.sal) order by sal desc;
I think that the query below will work just perfect on oracle sql...I have tested it myself..
Info related to this query : this query is using two tables named employee and department with columns in employee named: name (employee name), dept_id (common to employee and department), salary
And columns in department table: dept_id (common for employee table as well), dept_name
SELECT
tab.dept_name,MIN(tab.salary) AS Second_Max_Sal FROM (
SELECT e.name, e.salary, d.dept_name, dense_rank() over (partition BY d.dept_name ORDER BY e.salary) AS rank FROM department d JOIN employee e USING (dept_id) ) tab
WHERE
rank BETWEEN 1 AND 2
GROUP BY
tab.dept_name
thanks
Another one for Oracle using analytic functions:
select distinct col1 --distinct is required to remove matching value of column
from
( select col1, dense_rank() over (order by col1 desc) rnk
from tbl
)
where rnk = :b1
Select min(fee)
from fl_FLFee
where fee in (Select top 4 Fee from fl_FLFee order by 1 desc)
Change Number four with N.
You can simplify like this
SELECT MIN(Sal) FROM TableName
WHERE Sal IN
(SELECT TOP 4 Sal FROM TableName ORDER BY Sal DESC)
If the Sal contains duplicate values then use this
SELECT MIN(Sal) FROM TableName
WHERE Sal IN
(SELECT distinct TOP 4 Sal FROM TableName ORDER BY Sal DESC)
the 4 will be nth value it may any highest value such as 5 or 6 etc.
(TableName=Student, ColumnName=Mark) :
select *
from student
where mark=(select mark
from(select row_number() over (order by mark desc) as t,
mark
from student group by mark) as td
where t=2)
In PostgreSQL, to find N-th largest salary from Employee table.
SELECT * FROM Employee WHERE salary in
(SELECT salary FROM Employee ORDER BY salary DESC LIMIT N)
ORDER BY salary ASC LIMIT 1;
Solution to find Nth Maximum value of a particular column in SQL Server:
Employee table:
Sales table:
Employee table data:
==========
Id name
=========
6 ARSHAD M
7 Manu
8 Shaji
Sales table data:
=================
id emp_id amount
=================
1 6 500
2 7 100
3 8 100
4 6 150
5 7 130
6 7 130
7 7 330
Query to Find out details of an employee who have highest sale/ Nth highest salesperson
select * from (select E.Id,E.name,SUM(S.amount) AS 'total_amount' from employee E INNER JOIN Sale S on E.Id=S.emp_id group by S.emp_id,E.Id,E.name ) AS T1 WHERE(0)=( select COUNT(DISTINCT(total_amount)) from(select E.Id,E.name,SUM(S.amount) AS 'total_amount' from employee E INNER JOIN Sale S on E.Id=S.emp_id group by S.emp_id,E.Id,E.name )AS T2 WHERE(T1.total_amount<T2.total_amount) );
In the WHERE(0) replace 0 by n-1
Result:
========================
id name total_amount
========================
7 Manu 690
Table employee
salary
1256
1256
2563
8546
5645
You find the second max value by this query
select salary
from employee
where salary=(select max(salary)
from employee
where salary <(select max(salary) from employee));
You find the third max value by this query
select salary
from employee
where salary=(select max(salary)
from employee
where salary <(select max(salary)
from employee
where salary <(select max(salary)from employee)));