MySQL query using count() and if/case - mysql

I need to find the count of users who have filled the questionnaire on that day.
These are the total counts , i need counts per day. Here is the picture of database: http://www.upload.ee/image/3800828/pildike.png
SELECT DISTINCT USER_ID, COUNT(ANSWER_TIME) AS ARV FROM RESULT WHERE ANSWER_TIME IS NOT NULL GROUP BY USER_ID ORDER BY ARV DESC;
For example this gives me:
32 2142
143 1098
26 979
76 878
But i need like distinct rows, answer_day_of_week is from 1 to 7, depending on day and answer_time is TIMESTAMP. The statistics is been for 97 days and for example person 32 has filled it 2000+ times in 97 days, but i only need to count them once...
I thought to use if-elseif or while or case or some sort of subquery ? I have tried some queries but i always fail...
For example for one day i can have 15 rows from one person on 1. oct but have 0 rows on 2. oct , then it gives answer that he has filled the survey only once.

SELECT USER_ID, COUNT(ARV) AS ARV
FROM
(
SELECT DISTINCT USER_ID, DATE(ANSWER_TIME) AS ARV FROM RESULT WHERE ANSWER_TIME IS NOT NULL
) A
GROUP BY USER_ID ORDER BY ARV DESC;
Please try the above query

Just change your sql query like this:
SELECT DISTINCT USER_ID, COUNT(ANSWER_TIME) AS ARV FROM RESULT WHERE DATE(ANSWER_TIME) >= DATE_SUB(CURDATE(), INTERVAL '97 DAYS') GROUP BY USER_ID ORDER BY ARV DESC;

Related

How can this SQL query be more efficient?

mysql 5.7
linux
The query below takes about 210 seconds on 9000 records. Not really desirable performance.
The data table has these fields:
login_attempt_id integer
user_id integer
login_attempt_data datetime
login_attempt_ip string`
I wish to query the data to find the number of IPs that have failed login. For example:
109 119.27.191.202
93 118.25.146.128
83 132.232.31.117
81 132.232.160.234
The query:
select count(t0.login_attempt_ip) as `ip_count`, t0.login_attempt_ip
from sohne_sma_v4.wp_login_fails t0
where t0.login_attempt_ip in
(select distinct t1.login_attempt_ip from sohne_sma_v4.wp_login_fails t1
where 20 <
(select count(t2.login_attempt_ip) from sohne_sma_v4.wp_login_fails t2
where t2.login_attempt_ip like t1.login_attempt_ip
)
)
and datediff(now(), t0.login_attempt_date) < 15
group by t0.login_attempt_ip
order by ip_count desc;
I can guess the time is spent in the two inner queries.
What is a better way to achieve this query?
You dont really need all these subqueries.
You can just user GROUP BY...HAVING to keep grouped items having count more than 20.
Something like this should work
https://www.db-fiddle.com/f/vCMPWJaRxeSPVVDNSPVhcD/0
SELECT COUNT(t.login_attempt_id) AS ip_count,t.login_attempt_ip FROM sohne_sma_v4.wp_login_fails t
WHERE datediff(now(), t.login_attempt_date) < 15
GROUP BY t.login_attempt_ip HAVING (ip_count> 20 )
ORDER BY ip_count DESC;

Mysql join table group by user id and score result with set max date

I am developing a WordPress website for e learning. So one student attends the course, many times and scored the mark many times. Now I need to get one id with score and last record. I have tried many examples, but am able to get the result. I have given below my code.
SELECT m.id
, m.email
, t.id_tracking
, t.user_id
, FROM_UNIXTIME(t.date)
, t.score
, t.groupe_id
FROM tracking t
join membres m
WHERE t.id_tracking IN (
SELECT MAX(date)
FROM tracking
GROUP BY user_id
)
I have used about the query I don't know what I did wrong
user_id email score date
1 test#testmail.com 78 15-06-2019
1 test#testmail.com 89 12-08-2019
2 sam#testmail.com 66 24-03-2018
2 sam#testmail.com 44 19-07-2019
3 siv#testmail.com 98 09-02-2019
3 siv#testmail.com 78 13-08-2020
I need to get result below like
user_id email score date
1 test#testmail.com 89 12-08-2019
2 sam#testmail.com 44 19-07-2019
3 siva#testmail.com 98 09-08-2020
You can GROUP BY email/user_id and select maximum of date from each group, by converting the date to a UNIX TIMESTAMP, like this
SELECT user_id, email, score, FROM_UNIXTIME(MAX(UNIX_TIMESTAMP(date)))
FROM tableName
GROUP BY user_id
I am not sure about your DB but,
Have you tried like this...
SELECT
*
FROM
(SELECT * FROM process_table ORDER BY date desc) tbl1
GROUP BY
tbl1.id

MySQL query to retrieve DISTINCT COUNT between moving DATE period

I'm trying to write a query that returns a list of dates and the DISTINCT COUNT of User IDs for the 7 days preceding each date. The table I'm working with is simple, and looks like this:
Started UserId
"2012-09-25 00:01:04" 164382
"2012-09-25 00:01:39" 164382
"2012-09-25 00:02:37" 166121
"2012-09-25 00:03:35" 155682
"2012-09-25 00:04:18" 160947
"2012-09-25 00:08:19" 165806
I can write the query for output of an individual COUNT as follows:
SELECT COUNT(DISTINCT UserId)
FROM Session
WHERE Started BETWEEN '2012-09-18 00:00' AND '2012-09-25 00:00';
But what I'm trying to do is output this COUNT for every day in the table AND the 7 days preceding it. To clarify, the value for September 25th would be the count of DISTINCT User IDs between the 18th and 25th, the 24th the count between 17th and 24th, etc.
I tried the following query but it provides just the COUNT for each day:
SELECT
DATE(A.Started),
Count(DISTINCT A.UserId)
FROM Session AS A
WHERE DATE(A.Started) BETWEEN DATE(DATE_SUB(DATE(DATE(A.Started)),INTERVAL 7 DAY)) AND DATE(DATE(A.Started))
GROUP BY DATE(A.Started)
ORDER BY DATE(A.Started);
And the output looks like this:
DATE(A.Started) "Count(DISTINCT A.UserId)"
2012-09-18 709
2012-09-19 677
2012-09-20 658
2012-09-21 556
2012-09-22 530
2012-09-23 479
2012-09-24 528
2012-09-25 480
...
But as I said, those are just the daily counts. Initially I thought I could just sum the 7 day values, but that will invalidate the DISTINCT clause. I need the DISTINCT UserId counts for each 7 day period preceding a given date.
This query should work for you:
SELECT
DATE_FORMAT(d1.Started, '%Y-%m-%d') AS Started,
COUNT(DISTINCT d2.UserID) Users
FROM
(
SELECT
DATE(Started) AS Started
FROM
Session
GROUP BY
DATE(Started)
) d1
INNER JOIN
(
SELECT DISTINCT
DATE(Started) AS Started,
UserID
FROM
Session
) d2
ON d2.Started BETWEEN d1.Started - INTERVAL 7 DAY AND d1.Started
GROUP BY
d1.Started
ORDER BY
d1.Started DESC
Visit http://sqlfiddle.com/#!2/9339c/5 to see this query in action.
try:
Select Distinct Date(A.Started), Count(B.UserId)
From Session a
Join Session b
On b.Start Between AddDate(A.Start, day, -7) And A.Start
I'm not a MySQL guy, so the syntax might not be correct, but the pattern will work....

SQL Running Total Grouped by Date

(Using SQL Server 2008) I could easily get this to work if I built a view, and then a query on the view, but I want to perform this in one SQL query. I have a table that contains two columns (DeliveredDate (DateTime), Delivered (Varchar)). I am first converting DeliveredDate to Date only, and then grouping by Date. At the same time I am performing a Count on Delivered (column is either YES or NULL). Here is what I use to accomplish this portion:
SELECT CAST([DeliveredDate] As Date),
COUNT([Delivered])
FROM [TableName]
GROUP BY CAST([DeliveredDate] As Date)
ORDER BY CAST([DeliveredDate] As Date)
As an output, I get something like:
DeliveredDate | Delivered
2012-04-24 10
2012-04-25 500
2012-04-26 422
2012-04-27 33
What I'm looking for is something like this:
DeliveredDate | Delivered | RunningTotal
2012-04-24 10 10
2012-04-25 500 510
2012-04-26 422 932
2012-04-27 33 965
I've tried various examples I've seen out there, but none seem to match this scenario of performing a Count and a RunningTotal on said Count.
If you are using a product that implements ordered OVER clauses for SUM, you can do something like this:
select
cast(DeliveredDate as date) as DeliveredDate,
count(Delivered) as Delivered,
sum(count(Delivered)) over (
order by DeliveredDate
) as RunningTotal
from Orders
group by OrderDate
order by OrderDate;
Your expression count(Delivered) is a bit strange. Just to be sure it's what you want: it will count the number of rows on the particular date for which the value in the Delivered column is NOT NULL.
I'm not sure if a CTE counts as a view but this will work in SQL 2005+ which Does Not Support ordered OVER clauses for SUM,
WITH cte (DeliveredDate, Delivered)
AS (SELECT Cast([DeliveredDate] AS DATE) DeliveredDate,
Count([Delivered]) Delivered
FROM [TableName]
GROUP BY Cast([DeliveredDate] AS DATE))
SELECT d1.delivereddate,
d1.delivered,
Sum(d2.Delivered) RunningTotal
FROM cte d1
LEFT JOIN cte d2
ON d1.delivereddate >= d2.DeliveredDate
GROUP BY d1.delivereddate,
d1.delivered
ORDER BY d1.delivereddate

How to use query results in another query?

I am trying to write a query which will give me the last entry of each month in a table called transactions. I believe I am halfway there as I have the following query which groups all the entries by month then selects the highest id in each group which is the last entry for each month.
SELECT max(id),
EXTRACT(YEAR_MONTH FROM date) as yyyymm
FROM transactions
GROUP BY yyyymm
Gives the correct results
id yyyymm
100 201006
105 201007
111 201008
118 201009
120 201010
I don’t know how to then run a query on the same table but select the balance column where it matches the id from the first query to give results
id balance date
120 10000 2010-10-08
118 11000 2010-09-29
I've tried subqueries and looked at joins but i'm not sure how to go about using them.
You can make your first select an inline view, and then join to it. Something like this (not tested, but should give you the idea):
SELECT x.id
, t.balance
, t.date
FROM your_table t
/* here, we make your select an inline view, then we can join to it */
, (SELECT max(id) id,
EXTRACT(YEAR_MONTH FROM date) as yyyymm
FROM transactions
GROUP BY yyyymm) x
WHERE t.id = x.id