MySQL: SQL JOIN, COUNT, and WHERE statements - mysql

Currently, I am trying to join two tables (named pageviews and sessions) and use the COUNT and WHERE conditions in order to identify new users that used the site (on a specific page) from the previous two weeks. For reference, the two tables date back from the previous 12 months. In order to do so, I have written the following query
SELECT pageviews.pageType
, sessions.sessionDate
, sessions.deviceType
, COUNT(visitorId)
FROM sessions
INNER JOIN pageviews
on sessions.sessionId = pageviews.sessionId
WHERE pageviews.pageType = 'Page1'
AND sessionDate BETWEEN '2018-04-26' AND '2018-05-08'
=! visitorId BETWEEN '2017-05-10' AND '2018-04-27'
ORDER BY sessionsDate;
I decided to join the two tables by session ID so I can dedicate COUNT to visitorId. Is there a more efficient way to write this?

You should make a group by pageviews.pageType and do the count in the visits, you will have the result per page

Related

How to limit Row result on query when no Primary Key in table

I'm new to SQL as for over 20 years I haven't touched a single code line, so it feels like starting over.
I have a database with two tables, one for Projects, and another one for the Milestones. What I'm trying to achieve is to have a query that will retrieve the latest Milestone logged for each project. That way I can build a report with one project line with the latest update only.
I've managed to build the query to retrieve 1 (One) Milestone Record for each project. However when I've logged more than one update for the same date, the query returns all of them. I've tried to utilize the rowid, but it didn't work.
Here my sample tables:
And the query I've tried to run that currently retrieves more than 1 record when milestone created the same date.
select PROJECT_DATA.PARTNER_NAME as PARTNER_NAME,
PROJECT_DATA.SOLUTION_STATUS as SOLUTION_STATUS,
PROJECT_DATA.STRATEGY_MANAGER as STRATEGY_MANAGER,
PROJECT_DATA.SOLUTION_TYPE as SOLUTION_TYPE,
PROJECT_DATA.INTEGRATION_METHOD as INTEGRATION_METHOD,
PROJECT_MILESTONE.MILESTONE as MILESTONE,
PROJECT_MILESTONE.COMPLETED_ON as COMPLETED_ON,
PROJECT_MILESTONE.NOTES as NOTES
from PROJECT_DATA JOIN PROJECT_MILESTONE PROJECT_MILESTONE ON PROJECT_DATA.ID=PROJECT_MILESTONE.PROJECT_ID
where PROJECT_MILESTONE.COMPLETED_ON = (Select MAX (PROJECT_MILESTONE.COMPLETED_ON)
FROM PROJECT_MILESTONE
WHERE PROJECT_DATA.ID=PROJECT_MILESTONE.PROJECT_ID)
Any help on how to limit the query result to just 1 (newest one) when logged in the same date, will be extremely helpful.
Assuming that Completed on has the time as well along with the date, all you need to do is select top 1 in the ORDER BY DESC
Something like
select top 1 PROJECT_DATA.PARTNER_NAME as PARTNER_NAME,
PROJECT_DATA.SOLUTION_STATUS as SOLUTION_STATUS,
PROJECT_DATA.STRATEGY_MANAGER as STRATEGY_MANAGER,
PROJECT_DATA.SOLUTION_TYPE as SOLUTION_TYPE,
PROJECT_DATA.INTEGRATION_METHOD as INTEGRATION_METHOD,
PROJECT_MILESTONE.MILESTONE as MILESTONE,
PROJECT_MILESTONE.COMPLETED_ON as COMPLETED_ON,
PROJECT_MILESTONE.NOTES as NOTES
from PROJECT_DATA JOIN PROJECT_MILESTONE PROJECT_MILESTONE ON
PROJECT_DATA.ID = PROJECT_MILESTONE.PROJECT_ID
order by COMPLETED_ON DESC
Also, the joining condition has to be specified after the "ON" in joins and then you can use where condition to filter out the data

mysql - how to include zeros in the count in only one single query

I only have one table to count, I am not using any join. Is this possible?
Select engagement_type as name, COUNT(engagement_type) as y
From events
group By engagement_type
order By engagement_type
But only result is 1 row with count per engagement_type. I want to show all count of accounts without any engagement_type. Like these:
Will appreciate your answers! Thanks!
If there is a lookup-table, say EngagementTypes, where all possible values of engagement types are stored, then you can query this table to get the full list of all types and do a LEFT JOIN to events table in order to get the corresponding count:
Select t1.engagement_type as name, COUNT(t2.engagement_type) as y
From EngagementTypes AS t1
left join events as t2 on t1.engagement_type = t2.engagement_type
group By t1.engagement_type
order By t1.engagement_type

Comparing Datetime / Timestamp Values From Two Databases for Employee Scheduling (MySQL)

My goal is to compare a table of employee schedules from one database, to their actual clock in times in another.
Here is the query I'm starting with to simply find a singular clock-in time when searching the clock-in database:
SELECT *
FROM `users_log`
WHERE `user` = 'Employee'
AND `type` = 'Login'
ORDER BY ABS(`logintime` - UNIX_TIMESTAMP(`scheduled_logintime_from_2nd_database`)))
LIMIT 1
Not sure on the best way to do this (specifically because using the ORDER BY in a subquery is iffy). But ultimately I'd want some sort of parent query / join that would join the two databases on the Employee Name (user), and show both the scheduled logintime, and actual logintime from the two databases.
In the above example, for scheduled_logintime_from_2nd_database I'm just using a text string for testing, eventually that'd be the actual column from the other database. (note one is a timestamp, the other a datetime, hence the UNIX_TIMESTAMP function).
You're very close.
I suggest you proceed as follows:
First, do an appropriate JOIN operation to gather your two sources of data together. Something like this:
SELECT DATE(ul.logintime) day,
ul.name, ul.logintime,
UNIX_TIMESTAMP(sch.scheduled_logintime) sched_time
FROM users_log ul
JOIN schedule sch ON ul.name = sch.name
AND DATE(ul.logintime) = DATE(sch.scheduled_logintime)
This should get you a bunch of rows, one or more for each day and user, showing scheduled and actual times.
Then you can use that as a subquery, perhaps doing something like this:
SELECT name, day,
MAX(ABS(logintime - sched_time)),
MIN(ABS(logintime - sched_time))
FROM ( SELECT DATE(ul.logintime) day,
ul.name, ul.logintime,
UNIX_TIMESTAMP(sch.scheduled_logintime) sched_time
FROM users_log ul
JOIN schedule sch ON ul.name = sch.name
AND DATE(ul.logintime) = DATE(sch.scheduled_logintime)
)
GROUP BY name, day
That should give you each name's best and worst adherence to a schedule in each day.

MySQL joined query with max dates from two tables

I got two tables that contain date and time stamps and trying to extract records by the latest date in both.
Table 1 (sessions):
id---login_date------------ip
01---2014-01-02 23:58:40---127.0.0.1
03---2014-01-01 13:20:16---127.0.0.1
01---2014-01-01 17:06:15---127.0.0.1
02---2013-12-30 14:34:39---127.0.0.1
*also multiple other non-date columns which are not playing part in this solution
Table 2 (reminders):
id---last_reminder---------next_reminder
03---2013-12-29 22:50:18---2014-01-07 22:50:18
02---2014-01-01 15:15:15---2014-01-09 15:15:15
02---2013-11-16 08:54:23---2013-11-23 08:54:23
Now this is the way I get all the latest logins from the first table for each user ID:
SELECT a.id, a.login_date
FROM sessions a
WHERE a.login_date = (
SELECT max(login_date) as login_date
FROM sessions
WHERE id = a.id
LIMIT 1
)
GROUP BY a.id
What I would like to get is not only the last login date for each user ID, but also the last sent reminder (if any). As this involves selecting two max dates I never get correct results.
Desired Result:
id---login_date------------last_reminder---------next_reminder------
01---2014-01-02 23:58:40---NULL------------------NULL---------------
02---2013-12-30 14:34:39---2014-01-01 15:15:15---2014-01-09 15:15:15
03---2014-01-01 13:20:16---2013-12-29 22:50:18---2014-01-07 22:50:18
Would anybody please help me out with this.
Thanks,
Simon
////////////////////////UPDATED 2014-01-04 WITH EXTRA COLUMNS////////////////////////////
Based on the request the above table structure was updated to contain extra fields, required to produce correct query results.
*note that next_reminder field will always have a value as it's calculated based on the last reminder value. The query will eventually check whether the next reminder is within certain timeframe too.
P.S. StackOverflow is full of very good answers when only one table contains the date and time stamp (from which I have built what I have got so far), however I could not locate any similar examples that would involve joining two tables and selecting max dates from each.
if you have only two columns per table, you can directly join it and use MAX() to get the latest record for each ID.
SELECT a.id,
MAX(login_date) latest_login_date,
MAX(last_reminder) latest_reminder
FROM sessions a
LEFT JOIN reminders b
ON a.id = b.id
GROUP BY a.id
SQLFiddle Demo

Counting records from another mysql table with a left join

I have two DB tables, one that store events and the second that stores any associated comments for that event.
DB Tables:
events: id, owner_id, timestamp
comments: cmt_id, parent_id(events id), cmt_time
I'm trying to get the last 5 comments for each event based on a specific owner_id.
This is how I'm joining my tables:
SELECT * FROM `events`
LEFT JOIN comments ON comments.parent_id=events.id
WHERE owner_id=X
ORDER BY timestamp DESC LIMIT 0,5
Any idea how I can get the number of comments based on the event_id?
Your question is about the number of comments for each event (at least as I interpret it). For this, you want to use a group by:
SELECT e.event_id, COUNT(c.parent_id) as NumComments
FROM events e left JOIN
comments c
ON c.parent_id=e.id
WHERE e.owner_id = X
group by e.event_id;
As for the query in your question. It does not do what you want it to do ("I'm trying to get the last 5 comments for each event based on a specific owner_id."). Instead, it is getting the last five comments for a given user. Period.
You can do the table join at then use the COUNT() function to count how many comments are associated with a given event_id
http://www.w3schools.com/sql/sql_func_count.asp
I would give an example but I'm not entirely sure what you would like your end dataset to look like. COUNT(col) will count the number of rows associated with the query result