Doctrine Query <timestamp - sql

I have a colum "datetime", like this: 2012-06-04 15:40:20.
I want to create a query in Doctrine that I get the data of previous time. Less than 2012-06-04 15:40:20. How can I realize that in Doctrine.
Sorry, I just have no clue.

If I understand your question correctly, I believe the syntax is just:
$datetime = // your timestamp
->where('t.somefield < ?', date('Y-m-d H:i:s', strtotime($datetime))

I am not familiar with Doctrine, but here is standard SQL to do what you want:
select *
from t
where t.datetime in (select max(datetime)
from t
where datetime < '2012-06-04 15:40:20'
)
If Doctrine supports standard SQL syntax, then something like this would work (you might have to input the date/time constant in a different way).

Related

AR/Arel - How can i compose a query to SELECT a conditional CONCAT of columns

I've got a model method that conditionally concatenates the user's username ("login") and real name, if they've saved a real name - otherwise it just shows the username. I'd like to rewrite the query in ActiveRecord or Arel.
It looks like I should use an Arel::Nodes::NamedFunction. But i don't understand how to do the conditional concatenation with a named function. (Does Arel know about "if"? I can't find any reference in the docs.)
def primer_values
connection.select_values(%(
SELECT CONCAT(users.login,
IF(users.name = "", "", CONCAT(" <", users.name, ">")))
FROM users
ORDER BY IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,
last_login, NULL) DESC,
contribution DESC
LIMIT 1000
)).uniq.sort
end
There's also similarly a conditional in ORDER BY.
While generally I abhor Raw SQL in rails given this usage I'd leave it as is. Although I might change it to something a bit more idiomatic like.
User
.order(
Arel.sql("IF(last_login > CURRENT_TIMESTAMP - INTERVAL 1 MONTH,last_login, NULL)").desc,
User.arel_table[:contribution].desc)
.limit(1000)
.pluck(Arel.sql(
'CONCAT(users.login,
IF(users.name = "", "",
CONCAT(" <", users.name, ">")))'))
.uniq.sort
Converting this to Arel without abstracting it into an object of its own will damage the readability significantly.
That being said just to give you an idea; the first part would be 3 NamedFunctions
CONCAT
IF
CONCAT
Arel::Nodes::NamedFuction.new(
"CONCAT",
[User.arel_table[:name],
Arel::Nodes::NamedFuction.new(
"IF",
[User.arel_table[:name].eq(''),
Arel.sql("''"),
Arel::Nodes::NamedFuction.new(
"CONCAT",
[Arel.sql("' <'"),
User.arel_table[:name],
Arel.sql("'>'")]
)]
)]
)
A NamedFunction is a constructor for FUNCTION_NAME(ARG1,ARG2,ARG3) so any SQL that uses this syntax can be created using NamedFunction including empty functions like NOW() or other syntaxes like LATERAL(query).

How to convert a table column data inside eloquent in laravel?

I am trying to convert the 'CHECKTIME' table column datetime to string for using the 'LIKE' operator in sql. The LIKE operator is not support the datetaime data type. So, I have to convert it into string to use LIKE. How can I do it in laravel eloquent? My Code in Controller:
$dailyData=CheckInOutModel::join('USERINFO', 'USERINFO.USERID', '=', 'CHECKINOUT.USERID')
->select('USERINFO.USERID as id','USERINFO.BADGENUMBER as bd', 'USERINFO.NAME as name','USERINFO.Image as photo','CHECKINOUT.*')
->where(CONVERT(VARCHAR(25),' CHECKINOUT.CHECKTIME'),'LIKE',$thisDay.'%')
->orderBy('CHECKINOUT.CHECKTIME','desc')->get();
The SQL Query that work to return the data:
SELECT CHECKINOUT.CHECKTIME
FROM CHECKINOUT
JOIN USERINFO ON USERINFO.USERID=CHECKINOUT.USERID
WHERE CONVERT(VARCHAR(25), CHECKINOUT.CHECKTIME, 126) LIKE '2021-11-23%';
First off, you can use the whereRaw() (see link) method to inject raw SQL in your query.
This would be something like this:
$dailyData=CheckInOutModel::join('USERINFO', 'USERINFO.USERID', '=', 'CHECKINOUT.USERID')
->select('USERINFO.USERID as id','USERINFO.BADGENUMBER as bd', 'USERINFO.NAME as name','USERINFO.Image as photo','CHECKINOUT.*')
->whereRaw('CONVERT(VARCHAR(25), CHECKINOUT.CHECKTIME) LIKE ?', $thisDay.'%')
->orderBy('CHECKINOUT.CHECKTIME','desc')->get();
But since you are working with dates, it's recomended to use dates all the way and not convert the data to compare strings.
Another approach would be to use whereBetween directly with dates. (see link)
Exemple :
$dailyData=CheckInOutModel::join('USERINFO', 'USERINFO.USERID', '=', 'CHECKINOUT.USERID')
->select('USERINFO.USERID as id','USERINFO.BADGENUMBER as bd', 'USERINFO.NAME as name','USERINFO.Image as photo','CHECKINOUT.*')
->whereBetween(
'CHECKINOUT.CHECKTIME',
[
$thisDay,
date('Y-m-d', strtotime('+1 day', $thisDay))
]
)->orderBy('CHECKINOUT.CHECKTIME','desc')->get();
I have over indented the relevent section to make it clear.
Reach out in comments if you have any issue or suggestion to improve it :)

changing sql statement to eloquent query

So I have an SQL statement as such;
AND created_at BETWEEN '20190601' and '20190630'
How do I change this to an eloquent query? Or is it better to just use a db:raw query?
All inputs are very much appreciated. Cheers!
You can try this :
$yourQuery->whereBetween('created_at', ['20190601', '20190630']);
Read more at whereBetween section in here
As you are comparing dates, then do this:
$fromDate = '20190601';
$toDate = '20190630';
$yourquery->whereBetween('created_at', array($fromDate->toDateTimeString(), $toDate->toDateTimeString()) )->get();

Need help converting SQL query to Ruby.

I'm new to Ruby on Rails. I'm trying to determine the proper ruby query for the following SQL query.
Select max(bid_amount) from biddings where listing_id = 1;
I need to extract the maximum value in the bid_amount column. But it has to have a dynamic listing_id.
Try:
Bidding.where('listing_id = :listing_id', listing_id: 1).maximum(:bid_amount)
Update:
To follow up on your comment: since you say you are passing in params[:id], it's best to convert that parameter to integer so that unwanted values don't go to the database. For e.g.
Bidding.where('listing_id = :listing_id', listing_id: params[:id].to_i).maximum(:bid_amount)

RoR Search conditions comparing two columns

What I basically want to do is the following:
a = Assignment.all(:conditions => { :end_date < :start_date })
I only want to select those records on which the end_date is before the start_date.
I actually don't want ending up writing a
for each, push to array if end_date is earlier than start_date.
How can I achieve this in a pretty 'Railsy'-way?
Thank you in advance.
Edit:
I think the problem is comparing the values of both columns. (Allmost) every query is comparing a cell-value to an input-value.
This is a shot in the dark, but maybe one in the right direction ?
Haven't figured out a solution.
It's been a while here but nevertheless, you can just use the ArelTable method:
t = Assignment.arel_table
Assignment.where(t[:end_date].lt(t[:start_date]))
The condition predicates documentation: http://www.rubydoc.info/github/rails/arel/Arel/Predications
The ArelTable documentation: http://www.rubydoc.info/github/rails/arel/Arel/Table
And a good guide: http://jpospisil.com/2014/06/16/the-definitive-guide-to-arel-the-sql-manager-for-ruby.html
a = Assignment.all(:conditions => ["end_date < ?", :start_date ])
Check this: http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-all
I am assuming that you are using ActiveRecord
try
a = Assignment.where('regioassignments.end_date < regioassignments.start_date')
use the tablename followed by the EXACT COLUMNNAMES in the database, since ActiveRecord recognizes this and uses this as SQL directly.
That means the columnname for end_date is probably assignment_expected_end_date from what I figured from one of your comments.
adapted from this answer