Count distinct does not work in Oracle SQL Developer - plsqldeveloper

I need to count distinct date in one column but I do not want to group by that.
Datasource table:
ID zip5 date volume
11 11111 01/03/16 5
12 11111 01/03/16 6
13 11111 01/04/16 7
My code:
Select zip5, count(ID), count(distinct (date)), sum(volume),
from table
group by zip5
Desired output:
zip5 count(ID) count(distinct (date)) sum(volume)
11111 2 1 11
11111 1 1 7
However, what I got is:
zip5 count(ID) count(distinct (date)) sum(volume)
11111 3 3 18

Most likely, the problem you are facing is that your date column has a time component -- and, alas, it is not shown when you select from the table.
You can truncate the date to remove the time component. So try this:
Select zip5, count(ID), count(distinct trunc(date)), sum(volume),
from table
group by zip5;

To get your desired output simple add the "DATE" column in the GROUP BY expression.
Select zip5, count(ID), count(distinct ("DATE")), sum(volume)
from "TABLE"
group by zip5,"DATE"
order by 1,2;
ZIP5 COUNT(ID) COUNT(DISTINCT("DATE")) SUM(VOLUME)
---------- ---------- ----------------------- -----------
11111 1 1 7
11111 2 1 11
You may group by (i.e. select in disctinct rows) even columns that are not in the select list.

Related

How to select sum of column values using from and to time values? [duplicate]

I have a table with the following structure and sample data:
STORE_ID | INS_TIME | TOTAL_AMOUNT
2 07:46:01 20
3 19:20:05 100
4 12:40:21 87
5 09:05:08 5
6 11:30:00 12
6 14:22:07 100
I need to get the hourly sum of TOTAL_AMOUNT for each STORE_ID.
I tried the following query but i don't know if it's correct.
SELECT STORE_ID, SUM(TOTAL_AMOUNT) , HOUR(INS_TIME) as HOUR FROM VENDAS201302
WHERE MINUTE(INS_TIME) <=59
GROUP BY HOUR,STORE_ID
ORDER BY INS_TIME;
Not sure why you are not considering different days here. You could get the hourly sum using Datepart() function as below in Sql-Server:
DEMO
SELECT STORE_ID, SUM(TOTAL_AMOUNT) HOURLY_SUM
FROM t1
GROUP BY STORE_ID, datepart(hour,convert(datetime,INS_TIME))
ORDER BY STORE_ID
SELECT STORE_ID,
HOUR(INS_TIME) as HOUR_OF_TIME,
SUM(TOTAL_AMOUNT) as AMOUNT_SUM
FROM VENDAS201302
GROUP BY STORE_ID, HOUR_OF_TIME
ORDER BY INS_TIME;

Get Percentage of Last X entries in MySQL

I have 2 tables in MySQL(InnoDB). The first is an employee table. The other table is the expense table. For simplicity, the employee table contains just id and first_name. The expense table contains id, employee_id(foreign key), amount_spent, budget, and created_time. What I would like is a query that returns the percentage of their budget spent for the most recent X number of expense they've registered.
So given the employee table:
| id | first_name
-------------------
1 alice
2 bob
3 mike
4 sally
and the expense table:
| id | employee_id | amount_spent | budget | created_time
----------------------------------------------------------
1 1 10 100 10/18
2 1 50 100 10/19
3 1 0 40 10/20
4 2 5 20 10/22
5 2 10 70 10/23
6 2 75 100 10/24
7 3 50 50 10/25
The query for the last 3 trips would return
|employee_id| first_name | percentage_spent |
--------------------------------------------
1 alice .2500 <----------(60/240)
2 bob .4736 <----------(90/190)
3 mike 1.000 <----------(50/50)
The query for the last 2 trips would return
|employee_id| first_name | percentage_spent |
--------------------------------------------
1 alice .3571 <----------(50/140)
2 bob .5000 <----------(85/170)
3 mike 1.000 <----------(50/50)
It would be nice if the query, as noted above, did not return any employees who have not registered any expenses (sally). Thanks in advance!!
I'll advise you to convert datatype of created_time as DATETIME in order to get accurate results.
As of now, I've assumed that most recent id indicates most recent spents as it's what sample data suggests.
Following query should work (didn't tested though):
select t2.employee_id,t1.first_name,
sum(t2.amount_spent)/sum(t2.budget) as percentage_spent
from employee t1
inner join
(select temp.* from
(select e.*,#num := if(#type = employee_id, #num + 1, 1) as row_number,
#type := employee_id as dummy
from expense e
order by employee_id,id desc) temp where temp.row_number <= 3 //write value of **n** here.
) t2
on t1.id = t2.employee_id
group by t2.employee_id
;
Click here for DEMO
Feel free to ask doubt(s), if you've any.
Hope it helps!
If you are using mysql 8.0.2 and higher you might use window function for it.
SELECT employee_id, first_name, sliding_sum_spent/sliding_sum_budget
FROM
(
SELECT employee_id, first_name,
SUM(amount_spent) OVER (PARTITION BY employee_id
ORDER BY created_time
RANGE BETWEEN 3 PRECEDING AND 0 FOLLOWING) AS sliding_sum_spent,
SUM(budget) OVER (PARTITION BY employee_id
ORDER BY created_time
RANGE BETWEEN 3 PRECEDING AND 0 FOLLOWING) AS sliding_sum_budget,
COUNT(*) OVER (PARTITION BY employee_id
ORDER BY created_time DESC) rn
FROM expense
JOIN employee On expense.employee_id = employee.id
) t
WHERE t.rn = 1
As mentioned by Harshil, order of row according to the created_time may be a problem, therefore, it would be better to use date date type.

mysql count items in group_concat

I am having a trouble with using GROUP_CONCAT in MySQL
My tables g0 as follows:
ID Age Sex
-------------
1 16 Male
2 18 Female
3 16 Male
4 18 Female
5 16 Male
But I need the table to look like
ID count
1,3,5 3
2,4 2
I tried this query:
SELECT GROUP_CONCAT(
CONCAT(cnt)) cnts FROM
(SELECT COUNT(ID) as cnt FROM g0 GROUP BY Age , Sex order by ID Desc) ;
But I get this error message:
1248. Every derived table must have it's own alias
There's no need to have the count inside group_concat - just select it as a different item with the same group by expression:
SELECT GROUP_CONCAT(id), COUNT(*)
FROM g0
GROUP BY age, sex
ORDER BY 1 DESC

Sort the SQL table by name using maximum of quantity

I have an SQL selection which return the following:
Name Code Qty
Janet 10 6
Janet 11 9
Janet 09 8
Jones 12 7
Jones 11 8
James 09 5
James 10 4
I want this selection to get sorted based on the qty for all the three people : order the people by their maximum quantity, and then order by quantity.
The output should look like this:
Janet 11 9
Janet 09 8
Janet 10 6
Jones 11 8
Jones 12 7
James 09 5
James 10 4
Any way to achieve this?
This is a subtle problem. It looks like you want to sort the names by the maximum of qty. This requires a join and aggregation to get the maximum qty for each name:
select t.*
from table t join
(select name, max(qty) as maxq
from table t
group by name
) tt
order by tt.maxq desc, tt.name, t.qty desc;
Try this:
SELECT * FROM `names` ORDER BY name ASC, qty DESC
SELECT Name, Code, Qty
FROM names AS main JOIN
(SELECT Name, MAX(Qty) AS max_qty
FROM names
GROUP BY Name) AS max_names USING (Name)
ORDER BY max_names.max_qty DESC, names.Qty DESC
The virtual table max_names contains the maximal Qty for each Name:
Janet 9
Jones 8
James 5
Then you join it to the original table and sort according to this max_qty.
If you want to sort according to the total quantity per name, just replace MAX with SUM:
SELECT Name, Code, Qty
FROM names AS main JOIN
(SELECT Name, SUM(Qty) AS sum_qty
FROM names
GROUP BY Name) AS sum_names USING (Name)
ORDER BY sum_names.sum_qty DESC, names.Qty DESC
The sum_names table will contain:
Janet 23
Jones 15
James 9
You can specify more than one sorting condition:
SELECT * from names order by name, qty desc
Above query will sort by name and if names are equal then will sort by qty
If you want to select only higher qty for every user then use this query:
SELECT name, MAX(qty) FROM names GROUP BY name order by MAX(qty);

MySql Result Set Combine Columns

I have this result set from my query:
OrderId CustomerId ProducerId CustomerPayment ProducerPayment
1 1 3 10 5
1 1 4 10 5
1 2 3 10 5
1 2 4 10 5
I need to return this result into this:
OrderId UserId Payment
1 1 20
1 2 20
1 3 10
1 4 10
Just combining the CustomerId and ProducerId into UserId. Same with the Payment Columns.
Is there any way to achieve this with using just a simple select and group by? I'm avoiding temp tables, calling multiple same queries and like for optimization. I hope this is possible.
Thanks a lot
SELECT
OrderId,
CustomerID AS UserId,
SUM (CustomerPayment) As Payment
FROM orders
UNION ALL
SELECT
OrderId,
ProducerId AS UserId,
SUM (ProducerPayment) As Payment
FROM orders
Try something like this:
select
OrderId,
CustomerId,
sum(CustomerPayment) Payment,
group_concat(OrderId separator ',') listOrders /* list all OrderID's from the user and separates these with a , */
from your_table
group by CustomerId
Dont know how you query looks like atm?