SQL HELP - Latest date and unique by user - aggregate

NAME + LAST_LOGIN_DATE_TIME
=============================
Anna 12-DEC-14
Micky 24-JAN-15
Anna 31-JAN-15
Micky 09-FEB-15
Micky 02-MAR-15
I am looking to pull up unique name's with the latest date logged on date.
I would like the result to return:
Anna 31-JAN-15
Micky 02-MAR-15
Thanks in advance.

You can simple use MAX function like this:
select NAME , max(LAST_LOGIN_DATE_TIME )
from table_name
group by NAME;
Or you can also use OREDER BY, like this :
select NAME, LAST_LOGIN_DATE_TIME
from table_name t
where LAST_LOGIN_DATE_TIME in (select LAST_LOGIN_DATE_TIME
from table_name i where i.NAME = t.NAME order by LAST_LOGIN_DATE_TIME desc limit 1) ;

Related

How to get unique count without distinct

I must count a number of unique surnames and names in the Postgresql table.
The problem is usage of distinct is denied by task.
What I tried to do:
SELECT COUNT(SURNAME), COUNT (NAME) FROM PEOPLE GROUP BY NAME, SURNAME;
Output:
1 1 1 1 1 and etc
(4939 rows)
But it looks like I did something wrong because in output I must get only two digits with a count.
Any idea what to do with it?
You can get around using DISTINCT by first grouping by the name or surname, and then taking a count of that intermediate table.
SELECT
(SELECT COUNT(*) FROM
(SELECT SURNAME FROM PEOPLE GROUP BY SURNAME) t) AS surname_cnt,
(SELECT COUNT(*) FROM
(SELECT NAME FROM PEOPLE GROUP BY NAME) t) AS name_cnt

Need to select average age of employees department wise

I have a table in Postgresql DB. It has 3 fields: Emp_Name, Dept & Age. I need to show Average age of employees department wise. I need to display all 3 fields in the result-set. Below is the input and expected output:
Here is the SQL Fiddle : http://sqlfiddle.com/#!15/7c4cf
How do I show the expected result in PostgreSQL?
You can use the string_agg function to concatinate the employee names and avg to get the average age:
SELECT STRING_AGG(emp_name, ','), dept, AVG(age)
FROM test1
GROUP BY dept
SQLFiddle
You can use group by on Dept and use avg and string_agg aggregate functions to get the desired result:
select
string_agg(Emp_Name, ',') Emp_Name,
Dept,
avg(Age) Average_age
from test1
group by Dept;

Find most recent date

I have o table name table_1 with 4 columns id, text, fromDate, toDate. The table represents the working experience.I want to create a function which will return the row with columns id, text where the employee worked more recently. This means I need column toDate to be closest to today.
Here is a demonstration of my code:
Select (abs("toDate"-now())) as date_diff
from table_1
Select id,text
from table_1
where (abs("toDate"-now()))=select min(date_diff)
Is this correct or is there something better I can do?
I wil try something like this:
Select id,text
from table_1
where "toDate" = ( select max ("toDate") from table_1 )
It will provide you the latest "toDate" value.
Try this:
select * from table_1
order by to_date desc
limit 1

How to get firstname and second maximum salary of the record using subqueries?

I'm new to oracle. I have to get firstname and second maximum salary of the record from the table using sub-queries.
I've tried below query:
select max(salary)
from employees
where salary > (select max(salary)
from empoloyees);
this query used to get second max salary from the table. Now I have to get firstname of the second salary record.
firstname salary
-------------------
mani 45666
vijay 50000
sanjay 65000
SELECT firstname, salary FROM
(SELECT * FROM employees ORDER BY salary DESC)
WHERE rownum = 2;
The inner SELECT sorts the table by salary, in order from greatest to least (hence DESC).
The outer SELECT takes the two fields you want from row 2 (which holds the second highest salary) of the sorted table.
you can use dense_rank for this.
select firstname, salary
from (select /*+ first_rows(2) */ firstname, salary,
dense_rank() Over (order by salary desc) r
from employees)
where r = 2;
the first_rows hint is there as to help it use an index (index on (salary) or (salary, firstname).
This may return > 1 row if 2 people happen to share the same salary (you can add and rownum = 1 to pick just one at random).
Try this out
SELECT * FROM EMP WHERE SAL >=(SELECT MAX (SAL) FROM EMP WHERE SAL < (SELECT MAX(SAL) FROM EMP WHERE SAL <(SELECT MAX(SAL) FROM EMP))) AND ROWNUM < 4 ORDER BY SAL

Postgres: select the sum of values and then sum this again

I tried a lot but can´t find the right way.
If I select values in Postgres and sum them it looks like this:
SELECT name,sum(size) as total
FROM mytable group by name order by name;
How can I alter this so it also sum all values in total? I think I need a subselect but how?
Try this:
SELECT sum(a.total)
FROM (SELECT sum(size) as total
FROM mytable group by name) a
UPDATE
I'm sorry, I don't read that you want it all in the same query. For this reason the answer of greg it's better. However, other possibility if you have a postgresql version >= 9:
WITH mytableWith (name, sum) as
(SELECT name, sum(size)
FROM mytable
GROUP BY name)
SELECT 'grand total' AS name,
sum(sum) AS sum
FROM mytableWith
UNION ALL
SELECT name, sum
FROM mytableWith
I would use the ROLLUP function on POSTRGESQL:
SELECT name,sum(size) as total
FROM mytable
group by ROLLUP(name )
order by name;
This will give you a grand total of any value that you aggregate and can also be used for aggregating multiple columns.
Hope it helps!
If you want all results with the same SELECT, you could do something like
SELECT
'grand total' AS name,
sum(size) AS sum
FROM
mytable
UNION ALL
SELECT
name,
sum(size) AS sum
FROM
mytable
GROUP BY
name;
Hope it helps…
Well this should help you:
select sum(innerselect.innertotal) as outertotal from
(select sum(size) as innertotal from mytable group by name) as innerselect