Count DISTINCT on a single column over multiple conditions - mysql

I have a table, and I want to get the DISTINCT count of usernames over a certain period of time. Currently I'm running this query
SELECT DISTINCT username FROM user_activity WHERE company_id = 9 AND timestamp BETWEEN '2015-09-00' AND '2015-10-01' AND action = "Login Success";
It works great, however, I have multiple Companies that I want to select the count for. How do I expand the previous query to show me the distinct counts for multiple companies?
select count(distinct username),
sum(case when company_id = 1 then 1 else 0 end) A,
sum(case when company_id = 9 then 1 else 0 end) B
from `user_activity` Where timestamp BETWEEN '2015-09-00' AND '2015-10-01' AND action = "Login Success"
I've done something like this, however, I'm not getting the correct numbers. Ideally I would like to list each count as a different value for ease of reading, like the previous query illustrates. I don't need the count(distinct username) column to appear in my result, just the conditionals.
Thanks in advance.

If you don't mind two rows instead of two columns:
SELECT company_id, COUNT(DISTINCT username)
FROM user_activity
WHERE company_id IN (1,9)
AND timestamp >= '2015-09-01'
AND timestamp < '2015-09-01' + INTERVAL 1 MONTH
AND action = "Login Success"
GROUP BY company_id

Related

MYSQL GROUP BY 2 field with condition

need help
I have a table:
user | visit |....
user = 1,2,3,4
visit = 1,2,3,4
QUERY will work, but i want to agragate fields in MYSQL
SELECT COUNT(visit) as c, t.visit, t.user FROM t GROUP BY t.visit, t.user
I need return GROUP BY user fields without duplicate rows in filed user:
t.user, COUNT (t.visit where t.visit=1), COUNT( all t.visit)
user = 1 | visit1 = 10|. visit total = 100
......
To conditionally count a column, count the result of a CASE expression...
SELECT
t.user,
COUNT(CASE WHEN t.visit = 1 THEN 1 END) AS visit_1,
COUNT(*) AS visit_total
FROM
t
GROUP BY
t.user
Notes:
if a CASE expression doesn't have an ELSE clause, it defaults to ELSE NULL.
COUNT() only counts values that are NOT NULL.

Mysql - most efficient way to retrieve data based on multiple selects and wheres

I'm having trouble finding the most efficient way of retrieving various different sumed values from a Mysql table.
Let's say I've got 4 columns - userid, amount, paid, referral.
I'd like to retrieve the following based on a user id:
1 - the sum of amount that is paid (marked as 1)
2 - the sum of amount that is unpaid (marked as 0)
3 - the sum of amount that is paid and referral (marked as 1 on both paid and referral columns)
4 - the sum of amount that unpaid and referral (marked as 0 on paid and 1 on referral columns)
I've tried an embedded select statement like this:
SELECT (
SELECT sum(payout)
FROM table1
WHERE ispaid = 0 and userid = '100'
) AS unpaid
(
SELECT sum(payout)
FROM table1
WHERE ispaid = 1 and userid = '100'
) AS paid,
(
SELECT sum(payout)
FROM table1
WHERE ispaid = 0 and isreferral = 1 and userid = '100'
) AS refpending,
(
SELECT sum(payout)
FROM table1
WHERE ispaid = 1 and isreferral = 1 and userid = '100'
) AS refpaid
This works, but its slow (or at least feels like it could be quicker) on my server, around 1.5 seconds.
I'm sure there is a better way of doing this with a group statement but can't get my head around it!
Any help is much appreciated.
Thanks
You can use conditional expressions inside SUM():
SELECT
SUM(CASE WHEN ispaid=0 THEN payout END) AS unpaid,
SUM(CASE WHEN ispaid=1 THEN payout END) AS paid,
SUM(CASE WHEN ispaid=0 AND isreferral=1 THEN payout END) AS refpending,
SUM(CASE WHEN ispaid=0 AND isreferral=1 THEN payout END) AS refpaid
FROM table1
WHERE userid = '100'
If a given row is not matched by any CASE...WHEN clause, then the value of the expression is NULL, and SUM() ignores NULLs. You could also have an ELSE 0 clause in there if you want to be more explicit, since SUM() will not be increased by a 0.
Also make sure you have an index on userid in this table to select only the rows you need.

Nested Select Queries that Group By Similar Field

I have a database of Time Entries which stores userID, roundedHours, dateSpent, and taskID for each entry (these are daily timecards). I am trying to create one query that will output sums of roundedHours grouped by userID where the taskID meets a specific value between specified dates.
The code I've attempted is below. I need it to be output and grouped by userID but instead, my output is the total sum for both overhead_admin and total_hours (same on each row) and not specific to the userID.
SELECT userName, userID,
(SELECT sum(roundedHours)
FROM `db`.`TimeEntries`
WHERE taskId = 3050483 AND (spendDate BETWEEN '2020-11-02' AND '2020-11-08')) as overhead_admin,
(SELECT sum(roundedHours)
FROM `db`.`TimeEntries`
WHERE (spendDate BETWEEN '2020-11-02' AND '2020-11-08')) as total_hours
FROM `db`.`TimeEntries`
GROUP BY userID
Can anyone help me so that each row will have the total SPECIFIC to that user and NOT summed as a whole? The output I'm getting that is wrong is shown in the image below:
Use conditional aggregation:
SELECT userName, userID,
sum(case when taskId = 3050483 AND (spendDate BETWEEN '2020-11-02' AND '2020-11-08' then roundedHours end) as overhead_admin,
sum(case when spendDate BETWEEN '2020-11-02' AND '2020-11-08' then roundedHours end) as total_hours
FROM `db`.`TimeEntries`
GROUP BY userID

How To Find Duplicate, Count and Sum Values from different columns in MySQL?

I have my table
I want to get duplicates from the Name and Status column, count them, and sum values from the Sum column. I want to look like this:
I am new to SQL so that it may be an easy answer, but I can't seem to find a solution.
This is how far I got, but I can't seem to get the count and sum without errors.
SELECT name, COUNT(*) AS recovered
FROM complaints
WHERE status = "Recovered"
GROUP BY name
HAVING COUNT(name) > 0
myQuery
You can do conditional aggregation:
select
name,
sum(status = 'Recovered') recovered,
sum(status = 'Unrecovered') unrecovered,
sum(case when status = 'Recovered' then `sum` end) total_recovered_value,
sum(case when status = 'Unrecovered' then `sum` end) total_unrecovered_value
from mytable
group by name
order by name
Side note: sum is a language keyword, hence not a good choice for a column name.

Select count of customers that purchased at least one from two specific categories in the same month

I'm trying to write a query to count the customers that purchased at least one from order_type=0 and one order_type=1 during the same month in 2014
I have two tables.
The order table that have:
order_id
customer_id
aquisition_date
orders_category table:
order_id
order_type (the type of the orders it may have 0, 1, 2, 3, 5, 8 ...etc )
I tried with this query but it didn't work, I know it's not complete and I missed the month condition!
Select count(user_id) From order
join orders_category
on order.order_id = orders_category.order_id
Where (order_type=0 or order_type=1)
and extract (year from order.aquisition_date)=2014
group by user_id
having count (case when type_id=0 then null else null end) > 0
and count (case when type_id=1 then null else null end) > 0;
I don't know how to find users with at least 1 order from order_type=0 & 1 order of order_type=1, in the same month.
You could use this query, based on what you already had. However, I suggest you change the name of the table order to orders as order is a reserved word:
select count(distinct user_id)
from (
select user_id, month(aquisition_date)
from orders
inner join order_category
on orders.order_id = order_category.order_id
where order_type in (0, 1)
and year(aquisition_date) = 2014
group by user_id, month(aquisition_date)
having count(distinct order_type) = 2
) as base
SQL fiddle
I selected the month also in the sub-select, as it will be interesting to look at the output of that query on its own during your analysis.