I have a table of data with the following fields
EventID : Int, AutoIncrement, Primary Key
EventType : Int ' Defines what happened
EventTimeStamp : DateTime ' When the Event Happened
UserID : Int ' Unique
The query needs to tell me how many events occurred with new UserIDs for each day in the whole set. So, for each day, how many events exist which have a UserID which doesn't exist in any prior day. I've tried lots, and I can get unique users per day, but can't work out how to get 'NEW' users per day.
Select count(EventId) from table
where
UserId
not in (select UserId from table where EventTimeStamp < now() - interval 1 day)
Thank you all for your help - I've voted up the assistance. Here's what I did:
I created these 2 views (I needed to end up with a view, and had to create 2 as it seems you can't nest select statements within views).
Sightings:
select min(to_days(`Events`.TimeStamp)) AS Day0,
`Events`.TimeStamp AS TimeStamp,
`Events`.UserID AS UserID
from `Events` group by `Events`.UserID order by `Events`.UserID
NewUsers:
select count(distinct Sightings.UserID) AS Count,
date(Sightings.TimeStamp) AS Date from Sightings
group by date(Sightings.TimeStamp)
Good question. I don't have an exact solution but here's the approach I've seen before:
Do a SELECT where you compare the EventTimeStamp with MIN(EventTimeStamp) for a given userID, as determined by a nested SELECT statement on the same table to calculate the MIN timestamp for each ID (e.g. GROUP BY UserID).
First get a table b with for each user when he first arrived,
then join that table to get all events for that user for that day.
SELECT DATE(a.EventTimeStamp), COUNT(*) FROM table a
JOIN
(SELECT MIN(EventTimeStamp) AS EventTimeStamp, UserID from table group by userID) b
ON a.UserID = b.UserID
AND DATE(a.EventTimeStamp) = DATE(b.EventTimeStamp)
GROUP BY DATE(a.EventTimeStamp)
86400-(EventTimeStamp) as new_users
Related
I have a Journeys table. One of the columns on this table is EventType that holds an integer.
EventType can only ever be 1, 2 or 3.
How can I make a selection that has the logic:
Find a record with EventType = 3 and then select all records before it until you get to a record with EventType = 1.
Basically, this table collects GPS data (Latitude and Longitude) for a journey.
EventType = 1 means Start of Journey
EventType = 2 means Everything between the Start and End of a Journey
EventType = 3 means End of Journey
The table Schema is:
MySQL isn't very good (I can do simple Select statements ...etc) but just couldn't think of a way for attempting this.
I would think you could do something like this:
SELECT *
FROM your_table
WHERE id > (SELECT MIN(id)
FROM your_table
WHERE EventType = 1)
AND id < (SELECT MAX(id)
FROM your_table
WHERE EventType =3)
This may not be the most elegant solution, but from what I tried, it worked.
I'm looking to find a way to display a list of users that have cancelled a booking today.
The way my system works when a user cancels a booking is by adding a record into a cancellations table and deleting the record from the bookings table.
Currently I have
select distinct
members.firstname, members.lastname, cancelations.time, cancelations.groupnumber
from
members inner join cancelations on members.memberid = cancelations.memberid
where
cancelations.date = "CURRENT_DATE"
This works perfectly fine, except, this will also show if a user moves their appointment to a later/earlier time as the system will cancel then re-book.
So i believe what I would need is something like:
select distinct column names from tables where cancelations.date = "CURRENT_DATE" AND where the user hasn't got any records in the bookings table today
Tables in use (simplified)
Members - memberid, firstname, lastname
Cancelations - cancelationid, memberid, date, time, groupnumber
bookings - bookingid, memberid,date,time,groupnumber
So use NOT EXISTS() which is exactly what you are asking for :
select distinct members.firstname, members.lastname, cancelations.time, cancelations.groupnumber
from members
inner join cancelations
on members.memberid = cancelations.memberid
where cancelations.date = "CURRENT_DATE"
AND NOT EXISTS(SELECT 1 FROM bookings b
WHERE DATE(b.dateField) = DATE(cancelations.date)
AND b.memberid = member.memberid)
This checks that a record in the same day for the same member doesn't exists in booking table
I would go about this by changing your table structure for the bookings table. Instead of storing the state of a cancellation across multiple tables, I would just add a new column to bookings called isActive. This column will be set to 1 when a booking is created and will be set to 0 when one is deleted. Also when a booking is restored, it will be set to 1. This is a common technique known as "soft" deletion. It allows you to logically delete a record without actually removing it or moving it to another table. At some later point, you can archive stale deleted bookings to another table.
Here is the table structure:
CREATE TABLE bookings (`id` int PRIMARY KEY,
`memberid` int,
`isActive` tinyint
`date` datetime);
Now the query to find out if the user does not have any bookings from today is sane and straightforward:
SELECT COUNT(*)
FROM bookings
WHERE memberid = 1 AND
date = CURDATE() AND
isActive = 1
The query given by #sagi looks promising, but when you find yourself writing complex queries to answer simple business questions it might pay to think about the architecture.
I have a table with columns:
id , conversation_id , session_id , user_id , message , created_at
every time a user starts a conversation with an employee, a new session starts (different session number).all messages between every employees and users are stored in this table. the created_at column is a timestamp. I need to filter out sessions by employee number, and calculate the average response time between the first message a user sends and the first message sent back by a specific employee, for every session disregarding outlying data where either a customer or employee did not reply ( only one user in the session)
i know this is complicated but please help!
in this example in the user_id column, 4 is the employee ( keep in mind there are other employees). everytime a new conversation starts the session_id changes. i have to go through each session for a specific employee, take the timestamp of the first message sent by the customer as well as the employee, take the difference, sum all the differences and then take an average, while making sure that the session actually contains two users ( filtering outlying data).
So far, ive come up with this:
SELECT * FROM messages
WHERE session_id IN (
SELECT session_id FROM messages
WHERE user_id =4 )
GROUP BY session_id, user_id
to get the first message from each customer and employee (gives something like this)
so from this specific example, i would omit line 41040 as it only as the session contains only 1 person (column 3, id 1028) and is considered outlying data
I'm actually appalled by some of the comments... StackOverflow is meant to be a community for helping others. Why bother even taking up comment space if you're gonna complain about my ponctuation or give a vague, useless answer?
Anyways, i figured it out.
Basically, i joined the same table multiple times but only queried the necessary data. In the first join, I queried the messages table with the employee messages and grouped them by session number. In the second join, i did the same procedure but only extracted the messages from the user. By joining them on the session id, it automatically omits any sessions where either a user or employee is not present. By default, the groupby returns the first set of data from the group ( in this situation i didn't have to manipulate the groupby because I was actually looking for the first message in the session), I then took the average of the difference between the message timestamp for the user and employee.In this specific situation, the number 4 is the employee number. Here is what the query looks like Also, the HAVING AVG_RESP > 0 was necessary in this situation to remove outlying data when tests are performed :
SELECT AVG(AVG_RESP)
FROM(
SELECT TIME_TO_SEC(TIMEDIFF(t.created_at, u.created_at )) AS AVG_RESP
FROM (
SELECT * FROM messages
WHERE session_id IN (
SELECT session_id FROM messages
WHERE user_id = 4) AND user_id = 4
GROUP BY session_id
) AS t
JOIN(
SELECT * FROM messages
WHERE session_id IN (
SELECT session_id FROM messages
WHERE user_id = 4) AND user_id != 4
GROUP BY session_id
) as u
ON t.session_id = u.session_id
GROUP BY t.session_id
HAVING AVG_RESP > 0
) as ar
Hopefully this helps someone in the future, unlike the people who leave ridiculous, useless comments.
I'm running this query, it works except it doesn't return what I need...
SELECT COUNT(up.profileOwnerUserNumber)
FROM profiles up
INNER JOIN userRatings ur
ON (ur.userRatingTargetUser = up.profileOwnerUserNumber)
WHERE ur.userRatingDateTime>(now()-INTERVAL 1 WEEK)
I get a return of 8 from this query. It's counting all instances found where (ur.userRatingTargetUser = up.profileOwnerUserNumber). But the userRatings table has 4 genuinely different entries in it - the other 4 are duplicates of numbers already found. I want my COUNT to return 4 - the number of distinctly different ur.userRatingTargetUser numbers found, not all 8 entries.
Table userRatings:
userRatingNumber int (autoincrement)
userRatingTargetUser int
Table profiles:
profileNumber int (autoincrement)
profileOwnerUserNumber int
Both userRatingTargetUser and profileOwnerUserNumber have int values that can match because they are set using another table:
Table users:
userNumber int (autoincrement)
How do I change my query so that I no longer count these extra records? SELECT DISTINCT didn't work.
Have you tried GROUP BY:
SELECT COUNT(up.profileOwnerUserNumber)
FROM profiles up
INNER JOIN userRatings ur
ON (ur.userRatingTargetUser = up.profileOwnerUserNumber)
WHERE ur.userRatingDateTime>(now()-INTERVAL 1 WEEK)
GROUP BY up.profileOwnerUserNumber
COUNT is an aggregate function, you should use GROUP BY.
http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html
I have Four Tables in database,
users, count, coupon, account
Need number of users from following conditions:
Select All Users from users table then
Select from count where users are not in the list of last 14 days then
Select users which are not in the list, to check that there are in coupon table. If they are not in coupon table then take those users id then
Select account table and check that these users have any count or insertion in the account table. If yes then set all those users in an array or print it out as a result.
Please anybody help me in forming good query?
Thanks!
If I'm right take users
who aren't in the count table for the last 14 days
and
who aren't in the coupon table.
and
who are in the account table
Seems like a weird sql but here is an example:
SELECT
*
FROM
user
WHERE user_id NOT IN
(
SELECT
user_id
FROM
`count`
WHERE
DATE_SUB(CURDATE(),INTERVAL 14 DAY) <= date_column
)
AND user_id NOT IN
(
SELECT
user_id
FROM
coupon
)
AND user_id IN
(
SELECT
user_id
FROM
account
)
If this isn't right, your explanation of what you want is wrong and should be clarified .
Everything could be wrong with this sql, because I don't know your columns (user id? date?) .But I think you can change the sql to your liking.