SQL Query :: parameters inside a Count? - mysql

Let's say I have a table of movie renters with columns:
UserID
MovieID
Rent_Start_date
Rent_Due_Date
I am trying to achieve an output table that looks like:
[UserID, Count of Movies Due in 1 Day, Count of Movies Due in 1 Week]
Is this possible to do in one single query? I currently have a php script that runs 1 query on movies due in 1 day and another query that runs movies due in 1 week. These two queries are then looped for every user ID, filling in the table essentially slot by slot. This is kind of slow.
By attempting to create this output with only 1 query, I tried something like:
SELECT UserID, count(movieID)
FROM MovieTable
GROUP BY movieID
But this doens't create columns of counts of expiration dates.
Is it possible to create a count column that has an arguement such as count( //all those satisfy where Rent_Due_Date - CURDATE() < ONE_WEEK)?

You need to group your results by user, not by movie:
SELECT UserID,
SUM(Rent_Due_Date BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL 1 DAY),
COUNT(*)
FROM MovieTable
WHERE Rent_Due_Date BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL 1 WEEK
GROUP BY UserID

Related

Selecting between the MIN date and MIN date + 11 months - MySQL

I have a table that lists an ID, a month, and a value. I'd like to query this table to find the min(month) where value <= 0.
I'm having trouble writing this in a way that doesn't call the same table multiple times as the table is about 10mm rows.
So far, what I've written uses a HAVING clause to check if the month between min(month) and min(month) + 11 but it isn't functioning correctly. The query returns no data.
select id, month from table
group by id
having month between min(month) and date_add(min(month), interval 11 month)
Is there a clean way to do this without nesting queries and calling the same table multiple times?
You basically need to scan the table twice. Basically, the query is something like this:
select t.*
from t join
(select id, min(yyyymm) as minyyyymm
from t
where val < 0
group by id
) tt
on t.id = tt.id and t.yyyymm >= minyyyymm and
t.yyyymm <= minyyyymm + interval 11 month;
One option for making this faster is to materialize the subquery and add an index on id.

Select all distinct values where datestamp is in the last 24 hours and order by total rows ASC

I have a query I am trying to formulate, but it keeps giving me unexpected results.
What I need to do is:
select all distinct values from my table where the unix timestamp is >= the last 24 hours, then order these results by which one has the highest amount of entries.
I have managed the time part:
SELECT DISTINCT(column_name) as myValue from table_name WHERE time_column >= unix_timestamp(CURRENT_TIMESTAMP, INTERVAL 1 DAY)
This works as expected. Then I was just going to use PHP to sort through the results etc etc, however I wish to use the power of SQL on this one.
Any ideas how I can extend the above query to encapsulate counting the amount of distinct column_name values? Also to then sort this in order dependent on how many values are in each one?
So essentially I want to get my results like so :
a unique ID | highest amount
a unique ID | second highest amount
a unique ID | lowest amount
I think you want to use group by for this query:
SELECT column_name as myValue, count(*) as cnt
from table_name
WHERE time_column >= unix_timestamp(CURRENT_TIMESTAMP, INTERVAL 1 DAY)
GROUP BY column_name
ORDER BY cnt;
I managed to figure it out, and in my case it works perfectly:
SELECT column_name, COUNT(*) as myValue
FROM table_name
WHERE time_column >= unix_timestamp(CURRENT_TIMESTAMP - INTERVAL 1 DAY)
GROUP BY column_name
ORDER BY myValue DESC
This gave me the 3 values which I expected. Which were the 3 values in the last 24 hours, and they were ordered by the amount of occurrences of this were in the database table - I tested this by manually creating another occurrence of these and checking at each stage. Worked a treat

Combine Table Records per Day to Create 'Last Week' page

I apologize if this has been asked before.. I'm very new to developing and although I've tried searching a lot, I'm not really sure what to look for.
Anyway so I have a table which counts records being entered per day. It looks something like this (each record is represented by a letter) (assume today's date is 27/01/2013):
RECORD | COUNT | DATE
------A-----|-----4-----|27/01/2013
------B-----|-----7-----|27/01/2013
------B-----|-----3-----|24/01/2013
------C-----|-----8-----|22/01/2013
------A-----|-----2-----|19/01/2013
Each new post is checked in the table and it updates the count if the record already exists on the current day, otherwise a new record is created.
For the page which prints the records which have been added 'TODAY', I have the MySQL query
SELECT * FROM `table` ORDER BY `date` DESC, `count` DESC LIMIT 1000
and use a php 'if' statement to only print the records where the date('Y-m-d') = date in the table. So only the records and the corresponding count which has been entered that day are printed.
- the table above would produce the result:
1. B 7
2. A 4
What I would like is a page which prints the records which have been entered in the last week. I know I can use DATE_SUB(now(),INTERVAL 1 WEEK) AND NOW(), to print the records from last week but I need to duplicate records to be combined and the counts added together.. so the result for this table would look like this:
1. B 10
2. C 8
3. A 4
How would I go about combining those duplicate records and have a list of records ordered by count? Is this the best method to get a 'last week' record count, or is there another table structure which would be better?
Again I'm sorry if this a silly question or if my explanation was long-winded, but just some simple pointers will be really appreciated.
Try this
SELECT `record`, SUM(`count`) AS `count`
FROM `table`
WHERE `date` > DATE_SUB(CURDATE(),INTERVAL 1 WEEK)
GROUP BY `record`
ORDER BY `count` DESC
And you can LIMIT 1000 grouped resultset if you need to
Using GROUP BY will allow you group related records together
SELECT `record`
, SUM(`count`) AS `count`
FROM `table`
WHERE `date` > `date` - INTERVAL 1 WEEK
GROUP BY `record`
ORDER BY `count` DESC
LIMIT 1000

Count number of bookings between a set of specified dates

I have a table of bookings. I want to count how many bookings occur on each day, starting from specified check in date and check out date. Eg. if check in date was 10-06-2012 and check out date was 14-06-2012 I require a table like this
Date Bookings
10-06-2012 1
11-06-2012 1
12-06-2012 2
13-06-2012 4
14-06-2012 3
I am struggling to get this working. I can count bookings in between the dates but not for each date between check in date and check out date.
I am not sure I understand your question. The query below assumes:
Your bookings table has (at least) columns date, checkin, checkout.
You are looking for bookings where checkin >= 10-06-2012 and checkout <= 14-06-2012.
Here is the query:
SELECT date, COUNT(*)
FROM bookings
WHERE checkin >= '2012-06-10' AND checkout <= '2012-06-14'
GROUP BY date
Use SUM() to find total bookings between a date range.
Try Below :
SELECT Date,SUM(Bookings)
FROM tablename
WHERE Date between 'startdate' AND 'enddate'
GROUP BY Date
First thing you need is a table of dates, day by day. Now mysql is not my thing, so I will try to write down as much info on what I'm doing as I can. Please correct these examples.
Table of dates might be prepared by a job checking for the last booking date and adding missing dates to table of dates. If this is not something you would accept, other solution is to create table dynamically, but there are some perils. To my knowledge there is no way to create such a table, but you can do a practically-working surrogate by selecting distinct dates from your booking table and cross joining this with table of days made in query itself:
((select distinct checkIn from bookings union select distinct checkOut from bookings)
cross join (select 0 union select 1 union select 2 ...))
The list of days should contain as many days as the biggest gap between checkin dates and each checkin and checkout date. This is something you will have to keep an eye on, or simply make the list sufficiently large, for example a hundred days.
Now that you have a table of dates, you need to count bookings matching this date. Complete query would look like this:
select tableOfDates.date, count(bookings.checkIn) bookings
from
(
(
select distinct dates.date + INTERVAL days.day DAY -- OR HOWEVER you add days in mysql
from
(select distinct checkIn date from bookings union select distinct checkOut from bookings) dates
cross join (select 0 day union select 1 union select 2 union 3 union 4 union 5 union 6 union 7) days
)
) tableOfDates
left join bookings
on tableOfDates.date between bookings.checkIn and bookings.checkOut
where tableOfDates.date between [YOUR DATE RANGE]

Selecting records in order of the number of records that contain a certain field

We have a table that is arranged as such: ID, Album_ID and Time_Voted. Each time a user votes,
it creates a new record. We'd like to display the top five Album_IDs, (which had the most records containing that Album_ID at the end of every week). The only way I know how to do this is to SELECT all records from the past week, then run a "while" on the results,then iterate through an array and and add a +1 to the corresponding Album_ID key each time it finds an instance of the same Album_ID. This is quite inefficient, and I'm convinced there's a good way to do this via SQL query, but it's beyond my level of knowlege.
So the question is, is there a way to, via query, get a count of each number of album_IDs, and then arrange by that count?
Here's the original SQL statement I was working with. The YEARWEEK stuff was just to get last week.
SELECT * FROM wp_album_votes WHERE YEARWEEK( Time_Voted ) = YEARWEEK( CURRENT_DATE - INTERVAL 7 DAY ) ORDER BY Album_ID
SELECT Album_ID, COUNT(*) AS NumVotes
FROM wp_album_votes
WHERE YEARWEEK( Time_Voted ) = YEARWEEK( CURRENT_DATE - INTERVAL 7 DAY )
GROUP BY Album_ID
ORDER BY NumVotes DESC LIMIT 5
select album_id, count( album_id )
from wp_album_votes
group by album_id
order by 2 desc.
you can wrap your other text and dates onto this basic structure...