Trying to get the first record for each day of the week in Rails via SQL if possible - sql

I have a weekly view of projects. For each project I'm grabbing the first record for each day of the week. It's important to me to always get the first record for that day, and know which weekdays have no records. Right now I'm doing this with a separate SQL string for each project + day of week combo in a nested for loop.
This feels wrong. It seems like I should be able to get this with ActiveRecord / SQL via Group By and Limit, and use Ruby/Rails to process the results. Is this possible?
Thanks in advance.
– David

Does that do the job? (Using MySQL)
#projects = []
for day in 1..7
#projects.push Project.where("DAYOFWEEK(project_date) = ?", day).where(:project_date => Time.now.all_week).order('project_date desc').first
end
#Time.now.all_week assumes you're working with Rails 3.2
Take a look at DATEOFWEEK() in MySQL docs
You can test with
for pj in #project
p pj.project_date if pj.project_date #nil if no project found
end

Related

Is there a way to filter which Form records are shown with Query results?

For background, I have 2 tables here. One is a JobTicket table with all of our required production info, and the other is a ScheduledItems table with all of our job ticket data, plus the dates we are supposed to run that Job. I am having no trouble getting all of the necessary data over there, my issue comes when I would like to do the opposite. I have created a Query to search for the Sales Order Number from both tables, and then set the criteria for Scheduled Items to null so it will only show the unscheduled Jobs. Query works great, shows me all of the jobs that have not been Scheduled yet, but for the life of me I cannot figure out the best way to go about filtering my Form JobTicket to show only those unscheduled Jobs. I don't want to just give my coworker those Query results and tell him to search Jobs one by one; some days we can get 25+ Jobs with 10+ Line Items, so the extreme end we would be looking at around 250 manual searches a day.
If anyone has dealt with this in the past and has any sort of jumping off point or recommendation for my methodology I would very sincerely appreciate it. Thanks all
the acess query
SELECT
Qry_JobTicket.Sales_Order_Number,
Qry_ScheduledItems.Sales_Order_Number
FROM Qry_JobTicket
LEFT JOIN Qry_ScheduledItems
ON Qry_JobTicket.Sales_Order_Number = Qry_ScheduledItems.Sales_Order_Number
WHERE (((Qry_ScheduledItems.Sales_Order_Number) Is Null));
Okay I have figured out how to go about it, all though I am sure it's not the best in the way of design principles. Here goes:
After creating the Query (SQL shown above, Qry_UnscheduledList) to find all of the Un-Scheduled Jobs, I created another query that brought in my Qry_JobTicket and my Qry_UnscheduledList. I inner joined on Sales Order Number, so we only see the Jobs yet to be scheduled, and brought in every field from Qry_JobTicket. Once that was done, I then created a button on my form and inserted the code below to change the Form's Record Source, similarly to as #HansUp suggested with the FormFilter property.
Private Sub Btn_ToBeScheduled_Click()
DoCmd.OpenForm "Frm_JobTicket"
With Forms("Frm_JobTicket")
If .RecordSource = "Qry_JobTicket" Then
.RecordSource = "Qry_ToBeScheduled"
ElseIf .RecordSource = "Qry_ToBeScheduled" Then
.RecordSource = "Qry_JobTicket"
End If
End With
End Sub
Now as I said earlier this may not be the best designing, but I was doing research for about an hour and couldn't find very many people who needed to filter their FormA records based off of corresponding records that don't exist in their FormB.

Remove One Month Data from a BigQuery Table via Query

I am trying to Remove data from One month (July) but I can't manage to write properly the SQL query in the console.
I have tried the following code and worked fine. I just need to find to way to write the range of one complete month (July).
DELETE
FROM Sandbox.SandboxTable
where Date = '2018-12-09T00:00:00'
I have tried different possibilities but had syntax errors. I will strongly appreciate any help!
DELETE
FROM Sandbox.SandboxTable
where
Date >= '2018-07-01T00:00:00' AND Date <= '2018-07-31T23:59:59'

Rails - Complicated SQL Query

I need help with a query that does the following:
Start from the newest record and go downwards to the older records.
It needs to be ordered by created_at time.
If there are new records in the database by created_at time, retrive them but do not get records I already got from step 1.
I want to only get only 16 records at a time. That number can change later.
Do not retrive records I already sent from a previous time.
Also just to let you know, this is started via $.ajax.
Reason for this is because I am getting new + old records real-time to be sent to the client. Think something like like user starts off visiting the website and it gets the current records starting with new ones. Then the user can go get older records, but at the same request, it also retrieves the brand new records. With a twist of only 16 records at a time.
Do I make sense?
This is what I currently have for code:
RssEntry.includes(:RssItem).where("rss_items.rss_id in (?) AND (rss_entries.id < ? OR rss_entries.created_at > ?)", rssids, lid, time).order("rss_entries.id DESC").limit(16)
lid = last lowest id from those records
rssids = ids from where to get the records
time = last time it did the records call
That code above is only the beginning. I now need help to make sure it fits my requirements above.
UPDATE 1
Ok, so I managed to do what I wanted but in 2 sql queries. I really don't think it is possible to do what I want in one sql query.
Any help is greatly appreciated.
Thanks.
Firstly, use scopes to get what you want:
class RssEntry < ActiveRecord::Base
scope :with_items, includes(:RssItem)
scope :newer_first, order("rss_entries.created_at DESC")
def self.in(args)
where(id: args)
end
def self.since(time)
where('rss_entries.created_at > ?', time)
end
end
then
RssEntry.with_items.in(rssids).since(time).offset(lid).limit(16).newer_first
It should work as expected.

How to add certain days to a known date with Active Record query in Rails 3.2.8?

There is invoice table in our rails 3.2.8 app. We want to select the invoice which is/is not overdue. There are invoice_date (date) and credit_term (integer) in invoice table. The idea is that if the invoice_date + credit_term (day) > Date.today, then the invoice is not overdue. Otherwise, the invoice is overdue. Here is the idea (not working query):
Invoice.where("invoice_date + credit_term.days > ?", Date.today)
What's the right way to add credit_term days to the invoice_date in SQL query? We would like to have a DB independent solution. Thanks so much.
MySQL (you didn't specify your RDBMS):
Invoice.where("DATE_ADD(invoice_date, INTERVAL ? DAY) > ?", credit_term.days, Date.today)
I am in no means an expert in ActiveRecord's query interface, but I was unable to find such a thing like what you are needing, without (1) making some DB changes or (2) filtering the Invoices "manually" (via a Ruby code).
Here are your options:
Instead of having a credit_term field, you can either:
Replace it with a due_date column, OR
Add the due_date column and preseve the credit_term as well -- this won't break any of your existing code, and, unless you got >100 million invoices, it won't compromize your production DB server.
You can add a searcher (like Sphinx, via thinking-sphinx gem), and make an index for the Invoices. With a properly defined index, you can use Sphinx's query interface to find invoices meeting your condition (if you want me to give you a concrete example on this, do tell me and I will update this post with it). This approach has the advantages of:
Not changing your DB one bit.
Utilizing a very fast search engine with a search data which must be reindexed only once every 24 hours.
You can "manually" find the invoices you need via a Ruby code like this:
invoices = []
today = Date.today
Invoice.find_each do |i|
invoices << i if (i.invoice_date + i.credit_term) > today
end
Using find_each guarantees you that you are fetching the records in batches -- you are not fetching the entire table.
Why not do the date wrangling in ruby?
Invoice.where("invoice_date > ?", Date.today - credit_term)
This is also able to use an index on invoice_date to run the query whereas MySQL (for example) wouldn't be able to use such an index if you used Date_Add
You may want to consider using Date.current (which takes Time.zone into account) instead of Date.today (which doesn't)

SQL Filtering based on Calculated Time Slots

Im making a simple booking system for our projectors at work.
Here is the scenario. Each projectors can have its availability set to quarter hour segments throughout the entire day. i.e projector 1 is available between 8:15am - 1:45pm and 3pm-5:15pm each day (can also be changed to have different availabilities set for each day). A projector can be booked for anytime time segment during the day as long as it is available. So ive got that setup in my sql database (with my asp.net mvc front end).
The question i have is what is the best way to search on this scenario. i.e. UserA comes in and says find me the projectors that are available this friday between 12pm-3pm. Im struggling to write an efficient sql query that will filter this. My best option so far is to pull back all projectors and than programatically work out if they are available and not booked between this time. It works but it is incredibly inefficient. I stumbled an idea of using a temp table generated by a stored proc that can than be filtered but it isnt quite there.
Has anyone got any ideas how i could approach this?
Thanks in advance
I would probably have a table called ProjectorReservations which contained a start time and end time (amongst other fields you might care about i.e. who is renting the projector).
Searching a projector would look something like this:
SELECT projectorName
FROM Projectors
WHERE NOT EXISTS
(SELECT 1 FROM ProjectorReservations
WHERE Projectors.projectorName = ProjectorReservations.projectorName
AND (ProjectorReservations.startTime < {end_time}
OR ProjectorReservations.endTime > {start_time}))
That pretty much checks to make sure no reservations start before the one you are looking for ends and vice versa. Obviously you will need to swap in your fields accordingly but that should give you the general idea