I have following tables.
Case
ID
Name
1
Anton
2
Elfriede
3
Osram
Appointments
ID
Duration
Case
1
70
1
2
70
2
Fastdocu with out appointment
ID
Duration
Case
1
15
2
2
15
2
3
50
3
3
8
3
I need sum up all duration and all appointments and the cases that are not in Appointments.
The result should be
Duration 88
Appointments 3
Cases 1
Following Statement I have written
Select sum(duration), count(DISTINCT ID), SUM(IF(`Case` NOT IN (1,2),1,0)) From Fastdocu
Suddenly the result is
Duration 88
Appointments 3
Cases 2
I must sum only distinct ids at the cases count. But the distinct seems to be forbidden in the if.
How can I count the cases right?
Use COUNT() with a CASE expression instead of SUM():
SELECT SUM(duration) total_duration,
COUNT(DISTINCT ID) distinct_ids,
COUNT(DISTINCT CASE WHEN `Case` NOT IN (1,2) THEN `Case` END) cases_not_in_Appointments
FROM Fastdocu
Since COUNT() does not have an ELSE branch it will not count Cases that do not satisfy the condition Case NOT IN (1,2) because in this case the result of the CASE expression will be NULL.
If you want to count the distinct ids and not the distinct Cases change to:
COUNT(DISTINCT CASE WHEN `Case` NOT IN (1,2) THEN ID END)
See the demo.
Results:
total_duration
distinct_ids
cases_not_in_Appointments
88
3
1
Related
I have the below records in my table
ID Name Price
1 XYZ 100
2 XYZ 100
3 AAA 100
4 AAA 100
5 ABC 100
6 ABD 100
I would like to group single row entries into one group and multi-row entries into another group.
The Output will have only 2 rows- Single Entry and Multiple Entry and Percentage of the Price both Categories hold when compared with Total.
ABC and ABD are single Entries as they have only 1 row and XYZ and AAA are multiple entries as they have 2 rows. I would like to sum all Price columns of multiple entries and Single entries and then calculate the percentage
Output:
Category Percentage
Single_Entry 33.3% ABC and ABD: (200/600*100)
Multiple_Entries 66.7% XYZ and AAA: (400/600*100)
How to achieve this in mySQL.
I view this as two levels of aggregation:
select (case when cnt = 1 then 'single' else 'multiple' end) as entry_type,
sum(price) / sum(sum(price)) over() as ratio
from (select category, count(*) as cnt, sum(price) as price
from t
group by category
) c
group by entry_type;
You can use two levels of aggregation:
select category, 100 * sum(price) / sum(sum(price)) over() as percentage
from (
select sum(price) price,
case when count(*) = 1 then 'single entry' else 'multiple entriers' end as category
from mytable t
group by name
) t
group by category
How to get those entries which have more than 1 records?
If it doesn't make sense... let me explain:
From the below table I want to access the sum of the commission of all rows where type is joining and "they have more than 1 entry with same downmem_id".
I have this query but it doesn't consider more entries scenario...
$search = "SELECT sum(commission) as income FROM `$database`.`$memcom` where type='joining'";
Here's the table:
id mem_id commission downmem_id type time
2 1 3250 2 joining 2019-09-22 13:24:40
3 45 500 2 egbvegr new time
4 32 20 2 vnsjkdv other time
5 23 2222 2 vfdvfvf some other time
6 43 42 3 joining time
7 32 353 5 joining time
8 54 35 5 vsdvsdd time
Here's the expected result: it should be the sum of the id no 2, 7 only
ie. 3250+353=whatever.
It shouldn't include id no 6 because it has only 1 row with the same downmem_id.
Please help me to make this query.
Another approach is two levels of aggregation:
select sum(t.commission) income
from (select sum(case when type = 'joining' then commission end) as commission
from t
group by downmem_id
having count(*) > 1
) t;
The main advantage to this approach is that this more readily supports more complex conditions on the other members of each group -- such as at most one "joining" record or both "joining" records and no more than two "vnsjkdv" records.
Use EXISTS:
select sum(t.commission) income
from tablename t
where t.type = 'joining'
and exists (
select 1 from tablename
where id <> t.id and downmem_id = t.downmem_id
)
See the demo.
Results:
| income |
| ----- |
| 3603 |
You can use subquery that will find all downmem_id having more than one occurrence in the table.
SELECT Sum(commission) AS income
FROM tablename
WHERE type = 'joining'
AND downmem_id IN (SELECT downmem_id
FROM tablename t
GROUP BY downmem_id
HAVING Count(id) > 1);
DEMO
In my table I have recorded various bits of information but the key fields for this problem are the subject_id and lesson_time where I want to group by subject to give a total count of rows for each day of week for each subject and total rows for each subject(weekly total), so from this sample data:
id subject_id lesson_time
1 4 2015-04-28
2 4 2015-04-28
3 3 2015-04-28
4 1 2015-04-28
5 4 2015-04-27
I want to count the totals for each subject for monday to friday and week total, so output for the above data example would be:
subject_id monday_total tuesday_total wednesday_total ... week_total
1 0 1 0 1
3 0 1 0 1
4 1 2 0 3
I can get total by subject easy enough as it is just count(*) after group by, what I am struggling with is the count for each individual day, my current (non working) query is
SELECT
subject_id,
COUNT( DAYOFWEEK(lesson_time)=2) AS monday_total,
COUNT( DAYOFWEEK(lesson_time)=3) AS tuesday_total,
COUNT( DAYOFWEEK(lesson_time)=4) AS wednesday_total,
COUNT( DAYOFWEEK(lesson_time)=5) AS thursday_total,
COUNT( DAYOFWEEK(lesson_time)=6) AS friday_total,
COUNT(*) AS week_total
FROM
tbl_lessons
GROUP BY
subject_id
Any help would be much appreciated.
try this
SELECT
subject_id,
SUM(DAYOFWEEK(lesson_time)=2) AS monday_total,
SUM(DAYOFWEEK(lesson_time)=3) AS tuesday_total,
SUM(DAYOFWEEK(lesson_time)=4) AS wednesday_total,
SUM(DAYOFWEEK(lesson_time)=5) AS thursday_total,
SUM(DAYOFWEEK(lesson_time)=6) AS friday_total,
COUNT(*) AS week_total
FROM
tbl_lessons
GROUP BY
subject_id
In mysql COUNT(n) counts every row (+ 1 for every row where n is not NULL). SUM(n) sums all n values (+ n for every row).
As boolean expression returns 1 or 0 SUM(DAYOFWEEK(lesson_time)=2) will return number of rows where DAYOFWEEK(lesson_time)=2 (it's like summing booleans 1+0+0+1+1+1+0+0+1+...)
SELECT date(lesson_time) AS lesson_time, count( * ) AS count FROM tbl_lessons GROUP BY date(lesson_time)
How can I count the total number of records, the number of unique of users and number of records on which the status is 2 from the table participants in one query?
I know how to accomplish this using 3 separate queries:
SELECT COUNT() FROM participants
SELECT COUNT() FROM participants GROUP BY user
SELECT COUNT(*) FROM participants WHERE status = 2
But this doesn't really seem efficient?
Table participants
id user status
10 john#example.com 1
11 john#example.com 1
12 john#example.com 1
13 sally#mailing.com 1
14 sally#mailing.com 2
15 edward#halloworld.com 1
16 edward#halloworld.com 1
17 edward#halloworld.com 2
18 mike#bestmail.net 2
19 mike#bestmail.net 1
29 nat#worldcom.com 0
Just use conditional aggregation:
select count(*) as numrecords, count(distinct user) as numusers,
sum(status = 2) as numstatus_2
from participants p;
Since you want just one result (per requirement), you don't need a group by clause at all, and all of these requirements can be created as arguments for the count function:
SELECT COUNT(*) AS total_records,
COUNT(DISTINCT user) AS distinct_users_count,
COUNT(CASE status WHEN 2 ELSE NULL END) AS status_2_count
FROM participants
I am using SUM() to count lines with multiple conditions in the following manner
SELECT date(time),
SUM(CASE WHEN crit1 = 1 AND crit2 NOT LIKE CONCAT('%',table1.id,'%') THEN 1 ELSE 0 END)
FROM table1, table2
GROUP BY date(time)
However what I noticed is that # of items that are counted is a multiple of items in the table1. So if there are 100 items that meet crit1 and crit2 criteria, and there are 5 items in table1, it would give me 500 items summed.
I added and removed items from table1 and it proportionally affected the SUM clause, to verify this.
How can it be summed without double counting for every case in CONCAT, or maybe a better way of counting all together?
Data structure:
table1 table2
id name time crit1 crit2
123 A 2013-05-15 05:00:00 1 456
234 B 2013-05-15 05:00:00 2 789
345 C 2013-05-15 05:00:00 1 678
Note: IDs are unique
Desired output:
2013-05-15 2
I believe you want this:
SELECT date(time), COUNT(crit2)
FROM table2
WHERE
table2.crit1 = 1
AND
table2.crit2 NOT IN (SELECT id FROM table1)
GROUP BY date(time)