i have a course table and a course due dates table like this
course_id | course_name
1 A
2 B
due_id | start_date | end_date course_id
1 2011-02-01 2011-02-28 1
2 2011-03-01 2011-03-15 1
now what i am trying to do from last tow day that write a query or code that will show a course name with current date session.for example if current date is betwen start and end date course should come like this and if its in next date session it should come with next due_id
course_id | course_name | due_id
1 A | 1
if this database structure is wrong for this please let me know
thanks for help
SELECT course.course_name, due_dates.course_id, due_id
FROM course
INNER JOIN due_dates ON course.course_id = due_dates.course_id
WHERE now() BETWEEN start_date and end_date;
Related
I have mysql table as follows:
|id | subject | link | week_number
------------------------------------
| 1 | ABC | link1 | week-1
| 2 | DEF | link2 | week-2
| 3 | GHI | link3 | week-3
------------------------------------
Now I want To show week-1 record to user for one week after login and from his registration date as initial date for week counting....
then in next week, week-1 and week-2 should be visible,
then in next week, week-1, week-2 and week-3 records should be visible.
I am completely blank...so didn't tried any code....
your help or guideline appreciated...
If you have a registration date, just make your live easier and change the column week_number to days_after_reg - and the values to 7,14,21
Then you just need to compare this number with the current offset:
SELECT * from linktable WHERE `days_after_reg` <= datediff(Now(), UserRegistrationDate)
Either insert the user date with a variable, or "join" the tables.
Note that the join has no join condition here, so don't forget to filter on user-id (or name or something).
SELECT l.subject, l.link from linktable l cross join
users u WHERE `l.days_after_reg` <= datediff(Now(), u.registrationDate)
and u.id=5
I am working with MySql and Symfony2. I need to build cohort analysis table. I need to compare how many users in each cohort log in to website at least once a week after they register. What I tried to do is to get number of registered users by week, basically these are my cohorts.
SELECT DATE_FORMAT(date_added,'%d %b %y') as reg_date, COUNT(*) AS user_count
FROM user
WHERE date_added>='2016-02-01' AND date_added<=NOW()
GROUP BY WEEK(date_added)
This query gets distinct users logged in to website by week.
SELECT WEEK(login_date) AS week, COUNT(DISTINCT user_id) AS user_count
FROM user_log
WHERE login_date>='2016-02-01' AND login_date<=NOW()
GROUP BY WEEK(login_date)
My problem: I can't figure out how to group logged in users by cohorts and compare cohorts by weeks. I hope I stated problem clearly. English is not my first language. Thanks.
Sample data:
user table
id | date_added (in WEEK() format)
A | 1
B | 1
C | 1
D | 2
E | 2
F | 2
G | 2
------------
user_log table
user_id | login_date (in WEEK() format)
A | 1
B | 1
B | 1
A | 2
D | 2
A | 2
D | 2
E | 2
Expected table. Cohort 1 - users registered in week 1, cohort 2- in week etc. Size - number of registered users. Week 1 - how many users logged back to website in a first week after registration, Week 2 - how many users logged back to website in a second week after registration
Cohort size Week1 Week2
Cohort 1 | 3 | 2 | 1 |
Cohort 2 | 4 | 2 | - |
This is borrowed from my modification of #Andriy M's answer of this question: Cohort analysis in SQL
This query gets unique user logins by week after registering.
SELECT DISTINCT
user_id,
FLOOR(DATEDIFF(user_log.login_date, user.date_added)/7) AS Offset
FROM user_log
LEFT JOIN user ON (user.id = user_log.user_id)
WHERE user_log.login_date >= CURDATE() - INTERVAL 14 DAY
This query gets all the users created in the past 14 days and formats the date to the week they signed up:
SELECT
id,
DATE_FORMAT(date_added, "%Y-%u") AS cohort
FROM user
WHERE date_added >= CURDATE() - INTERVAL 14 DAY
We can put those two queries together to get a table with how many people came back after registering:
SELECT STR_TO_DATE(CONCAT(u.cohort, ' Monday'), '%X-%V %W') as date,
SUM(s.Offset = 0) AS size,
SUM(s.Offset = 1) AS Week1,
SUM(s.Offset = 2) AS Week2
FROM (
SELECT
id,
DATE_FORMAT(date_added, "%Y-%u") AS cohort
FROM user
WHERE date_added >= CURDATE() - INTERVAL 21 DAY
) as u
LEFT JOIN (
SELECT DISTINCT
user_id,
FLOOR(DATEDIFF(user_log.login_date, user.date_added)/7) AS Offset
FROM user_log
LEFT JOIN user ON (user.id = user_log.user_id)
WHERE user_log.login_date >= CURDATE() - INTERVAL 21 DAY
) as s
ON s.user_id = u.id
GROUP BY u.cohort
ORDER BY u.cohort
Since we aren't counting how many people registered in a given week, we are assuming that they logged at lease once in the week they registered to give an accurate result for the size column.
Also you'll have to rework this to get a number for the cohort instead of the date, but I find dates more helpful.
Also you can extend this to more weeks - you'll have to change the number of days after INTERVAL in both subqueries, and you can add more rows on in the main select statement to get more weeks.
Any Idea how can I identify if there is new client added on my database.
I was thinking about identifying it thru date_added field.
id client_name date_added
---------------------------------
1 ABC 2013-01-02
2 XYZ 2013-01-03
3 EFG 2013-01-02
4 HIJ 2013-01-05
as you can see a new client added HIJ on 2013-01-05.
I was looking with this kind of result:
Client List
Total NO: 4
New Client
Total No: 1
Client Name: HIJ
add a field new to the table, default it to 1, on page load use that for the select and set it to 0 to indicate its not longer new.
It's hard to tell but based on your comment ...my reference date is 1 month interval... you might be looking for something like this
SELECT id, client_name, new_count, total_count
FROM
(
SELECT id, client_name
FROM clients
WHERE date_added BETWEEN CURDATE() - INTERVAL 1 MONTH AND CURDATE()
) c CROSS JOIN
(
SELECT
(
SELECT COUNT(*) new_count
FROM clients
WHERE date_added BETWEEN CURDATE() - INTERVAL 1 MONTH AND CURDATE()
) new_count,
(
SELECT COUNT(*) total_count
FROM clients
) total_count
) t
Obviously you can easily change CURDATE() with any other reference date in the past in this query and you get results for that date.
Lets assume that you have following sample data
+------+-------------+------------+
| id | client_name | date_added |
+------+-------------+------------+
| 1 | ABC | 2013-05-13 |
| 2 | XYZ | 2013-06-13 |
| 3 | EFG | 2013-06-13 |
| 4 | HIJ | 2013-08-11 |
+------+-------------+------------+
and today is 2013-08-13 then the output from the query will be
+------+-------------+-----------+-------------+
| id | client_name | new_count | total_count |
+------+-------------+-----------+-------------+
| 4 | HIJ | 1 | 4 |
+------+-------------+-----------+-------------+
You could remember, in your webpage or PHP script, the highest ID value previously seen. Or the highest timestamp (better than a date) previously seen.
I prefer ID or Version numbers for concurrency-related stuff (locking, finding the latest etc) -- since they should be defined to be ascending, can't suffer "same millisecond" collisions, and are more efficient.
I assume you're going to hold the "state" of your application (as to what the user has seen) in hidden fields in the form, or somesuch. This would then track the "last seen" and allow you to identify "newly added" since the last pageview.
If you expect to identify newly added when coming from a different page or logging onto the application, you'll need to store the "state" in the database instead.
That depends on what you consider NEW. You have to define what you're going to compare the records against (reference date). Once you define it, you could use a query like the following:
SELECT * FROM client WHERE date_added >= '$date'
where $date is the reference date.
I have this query which after checking various tutorials should work - but it doesn't.
$query="SELECT week, year, COUNT(week) AS week_no
FROM archive_agent_booking
LEFT JOIN invoice_additions ON invoice_additions.week = archive_agent_booking.week
WHERE client_id='$account_no' GROUP BY week, year ORDER BY week DESC";
The tables are as follows:
archive_agent_booking
+---------+----------+----------+----------+----------+---------+---------+
| job_id | week | year | desc | price | date | acc_no |
+---------+----------+----------+----------+----------+---------+---------+
invoice_additions
+---------+----------+----------+----------+----------+---------+
| acc_no | week | year | desc | am_price | am_date |
+---------+----------+----------+----------+----------+---------+
I basically want to count each week element from both tables and display them as one total even if one of the week values does not show in one of the tables. Don't know whether this is the best solution so I am open to alternatives.
select
week,
sum(items)
from
(
(select week, count(*) as items from archive_agent_booking group by week)
union
(select week, count(*) from invoice_additions group by week)
)
group by
week
Edit: i've made some huge assumption about what you want to see
With PHP and MySQL I am trying to display items with most votes over a certain period of time (24 hour, 1 week, 1 year, etc). When someone votes on an item, a table records the user, item id, vote, and time, like so:
Table1
username | itemid | vote | time
asdf | 127 | 1 | 1306726126
asdf | 124 | -1 | 1306726123
bob | 127 | 1 | 1306726129
bob | 124 | 1 | 1306726123
Now, I have another table with item details.
Table2
itemid | name | category | date | etc
What I WANT to do is call a table to display all the data from table 2 for only items with votes in the last 24hours and sort it by the votes. This means I need to SUM votes with TIME < 24 hours, then RIGHT JOIN (?) to my other database? I don't know, I am having difficulty figuring out how I should go about doing this. Any suggestiongs?
Something like this should work.
SELECT SUM(Table1.vote) as votes, Table2.* FROM Table2
LEFT JOIN Table1 ON Table1.itemid=Table2.itemid
WHERE Table1.`time`>=DATE_SUB(Table1.`time`, INTERVAL 24 HOUR)
GROUP BY Table1.itemid
ORDER BY Table1.votes DESC