Display MAX and 2nd MAX SALARY from the EMPLOYEE table - oracle-sqldeveloper

SELECT max(salary),
(SELECT MAX(SALARY) FROM EMPLOYEE
WHERE SALARY NOT IN(SELECT MAX(SALARY) FROM EMPLOYEE)) as 2ND_MAX_SALARY;
This is giving me the error: FROM keyword not found where expected

You want the top 2 of your table ordered by one of the columns (the FETCH NEXT clause is available from Oracle 12c R1)
SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 2
FETCH NEXT 2 ROWS ONLY;
Use
SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 2
FETCH NEXT 2 ROWS WITH TIES;
if you want to return all employees that have the 1st or 2nd highest salary: There might only be one highest salary amount in the company, but more than one employee who gets that amount. Those rows are the ties.

If you're on Oracle database version lower than 12c, rank analytic function might help.
For sample rows:
SQL> select * from employee order by salary desc;
ENAME SALARY
---------- ----------
KING 5000 --> highest salary
FORD 3000 --> Ford and Scott "share" the 2nd
SCOTT 3000 --> highest salary
JONES 2975
BLAKE 2850
CLARK 2450
ALLEN 1600
TURNER 1500
MILLER 1300
WARD 1250
MARTIN 1250
ADAMS 1100
JAMES 950
SMITH 800
14 rows selected.
In a subquery (or a CTE, as I did), calculate rank for each salary and then, in the main query, select rows that rank as to top salaries:
SQL> with temp as
2 (select ename,
3 salary,
4 rank() over (order by salary desc) rnk
5 from employee
6 )
7 select ename, salary
8 from temp
9 where rnk <= 2
10 order by rnk desc;
ENAME SALARY
---------- ----------
SCOTT 3000
FORD 3000
KING 5000
SQL>

SELECT MAX(salary) AS max_salary,
(SELECT MAX(salary)
FROM employee
WHERE salary NOT IN (SELECT MAX(salary)
FROM employee
)
) AS 2nD_max_salary
FROM employee;

Related

Quartiles calculation in Postgresql Query

I am having a hard time trying to get this done. I have the following table:
cod_prod seller price date
A Andres 10 anydate
A Paul 5 anydate
A Mike 2.5 anydate
A Josh 1.75 anydate
A Karen 7.5 anydate
.... ..... ... .......
I am trying to calculate quartiles of the price for each product and classify each seller's price into 4 quartiles.
The output I am expecting is:
Cod_Prod Seller Price Quartile 1stQ 2ndQ 3rdQ 4thQ
A Andres 10 4 2.5 5 7.5 10
A Karen 7.5 3 2.5 5 7.5 10
A Paul 5 2 2.5 5 7.5 10
A Mike 2.5 1 2.5 5 7.5 10
A Josh 1.75 1 2.5 5 7.5 10
.. ..... .... .... .... .. ... ...
This table has thousands of distinct cod_prod and thousands of sellers.
I am trying this query:
with cte as (
select seller, cod_prod, sum(price) as sum_price
from tablename
group by 2,1
)
select seller,
cod_prod,
sum_price,
ntile(4) over (partition by seller order by sum_price asc) quartile
from cte
But this not doing what I expect and still mising the 1stQ to 4thQ indicators bins
I tried many different things but this is the closest I got from what I want.
Can someone help me to solve it?
I am not sure if this query is exactly what you want, but I think can help you.
I calculated quartiles grouping by cod_prod.
WITH cte AS (SELECT seller, cod_prod, sum(price) as sum_price
FROM t
GROUP BY seller, cod_prod),
quartiles AS (SELECT
cod_prod,
percentile_cont(0.25) within group (order by sum_price asc) as "1stQ",
percentile_cont(0.50) within group (order by sum_price asc) as "2ndQ",
percentile_cont(0.75) within group (order by sum_price asc) as "3rdQ",
percentile_cont(1) within group (order by sum_price asc) as "4thQ"
FROM cte
GROUP BY cod_prod)
SELECT cte.*,
ntile(4) over (PARTITION BY cte.cod_prod ORDER BY sum_price ASC) quartile,
quartiles.*
FROM cte
INNER JOIN quartiles ON cte.cod_prod = quartiles.cod_prod;

Need to combine the sales of 2 records with different ID's and the record with highest sale id should be in the result set

I have a table with records belonging to same person but the person was assigned with 2 different id's.
I need to combine the sales and then hold on to the id having highest sales.
For Example:
ID Name Sales
1 ABC 10
4 ABC 60
5 xyz 100
6 xyz 10
I need result as
ID Name Sales
4 ABC 70
5 XYZ 110
Please help me with a sql query for the above.
try this:
create table #mytable
(id int,
name nvarchar(20),
Sales int)
insert into #mytable
values
(1,'ABC',10),
(4,'ABC',60),
(5,'xyz',100),
(6,'xyz',10)
select (select top(1) ID
from #mytable r2
where r2.name=r1.name
and r2.Sales=MAX(r1.Sales))as ID,
name,
sum(Sales)
from #mytable r1
group by name
drop table #mytable

Several top numbers in a column T-SQL

I have a table called _Invoice in SQL Server 2016 - like this:
Company InvoiceNo
-----------------
10 1
10 2
10 3
20 1
20 2
20 3
20 4
I want to get the highest value from all companies.
Like this:
Company InvoiceNo
-----------------
10 3
20 3
I want this data to then update another table that is called InvoiceSeries
where the InvoiceNo is higher than the NextNo in InvoiceSeries table
I am stuck with getting the highest data from InvoiceNo:
UPDATE InvoiceSeries
SET NextNo = -- Highest number from each company--
FROM InvoiceSeries ise
JOIN _Invoice i ON ise.InvoiceSeries = i.InvoiceSeries
WHERE i.InvoiceNo > ise.NextNo
Some example data:
Columns in InvoiceSeries Columns in _Invoices
Company NextNo Company InvoiceNo
10 9007 10 9008
20 1001 10 9009
10 9010
10 9011
10 9012
20 1002
20 1003
20 1004
If I understand correctly, you are looking for the HIGHEST common invoice number
Example
Select A.*
From YourTable A
Join (
Select Top 1 with ties
InvoiceNo
From YourTable
Group By InvoiceNo
Having count(Distinct Company) = (Select count(Distinct Company) From YourTable)
Order By InvoiceNo Desc
) B on A.InvoiceNo=B.InvoiceNo
Returns
Company InvoiceNo
10 3
20 3
EDIT - Updated for comment
Select company
,Invoice=max(invoiceno)
From YourTable
Group By company
This answer assumes there will be a record in the Invoice Series table.
--Insert Sample Data
CREATE TABLE #_Invoice (Company INT, InvoiceNo INT)
INSERT INTO #_Invoice(Company, InvoiceNo)
VALUES
(10 , 1),
(10 , 2),
(10 , 3),
(20 , 1),
(20 , 2),
(20 , 3),
(20 , 4)
CREATE TABLE #InvoiceSeries(Company INT, NextNo INT)
INSERT INTO #InvoiceSeries(Company, NextNo)
VALUES
(10, 1),
(20 ,1)
UPDATE s
SET NextNo = MaxInvoiceNo
FROM #InvoiceSeries s
INNER JOIN (
--Get the Max invoice number per company
SELECT Company, MAX(InvoiceNo) as MaxInvoiceNo
FROM #_Invoice
GROUP BY Company
) i on i.Company = s.Company
AND s.NextNo < i.MaxInvoiceNo --Only join to records where the 'nextno' is less than the max
--Confirm results
SELECT * FROM #InvoiceSeries
DROP TABLE #InvoiceSeries
DROP TABLE #_Invoice

PostgreSQL showing people that are born the same month

So let's say I have a table of:
Name Born
John 1994-01-01
John 1994-02-08
Jack 1995-03-09
Bob 1992-03-10
Tom 1995-07-13
Ronda 1984-01-25
And I want to make it that it only shows
John 1994-01-01
Ronda 1984-01-25
Jack 1995-03-09
Bob 1992-03-10
Because they are born in the same months.
I've tried different selects with EXTRACT and such but it doesn't seem to work for me:|
You can do this with window functions:
select t.*
from (select t.*,
count(*) over (partition by extract(month from born)) as cnt
from t
) t
where cnt > 1
order by extract(month from born);

Selecting only the values that are in the 75th percent tile and are above a constraint

I'm trying to get this query to work properly...
select salary from agent
where salary > 75000
ORDER BY salary ASC
LIMIT (select ROUND(count(salary) * .75) as TwentyFifthTile from agent)
some addition information about the rows:
166 rows – 25%
331 rows – 50%
497 rows – 75%
662 rows – 100%
These rows have salary 75,000 plus:
235 / 662 = ~.35
.35 * 662 = ~235 rows.
I'm trying to get the above query to return back all the rows that have salary greater than 75,000 but are still in the first 497 rows. When I run the above query it returns all the rows starting at 75,000 and limited by a 497 row return constraint.
I'm not sure how I can just return salaries of greater than 75,000 that are in the first 497 rows of the limit constraint.
You can divide the total number of rows by the current row number to get this:
select salary
from (
select salary,
count(*) over () as total_count,
row_number() over (order by salary) as rn
from agent
where salary > 75000
) t
where (rn / total_count::numeric) <= 0.75
order by salary asc
Use row_number:
select salary, row_number() over (order by salary) row_num
from agent
where row_num < (select ROUND(count(salary) * .75) from agent)
and salary > 75000