Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jjmu15's avatar

Where Query - using calculated date value from record in the DB

I need to run a query where the date matches a calculated value. The scenario is as below

$now = CarbonImmutable::now();
$tests = Test::active()->whereDate('start_date', '=', $now->subDays('DB_COLUMN_VAL'));

How would I go about this?

Thanks in advance

0 likes
24 replies
filipc's avatar

I think this will have to be done through SQL with raw. Not sure if this will work but worth a try:

$tests = Test::active()->whereRaw("start_date = DATE_SUB(NOW(), INTERVAL {{column_name}} DAYS)")

make sure to replace {{column_name}} with the column where you store the days

jjmu15's avatar

Thanks for the quick reply.

The above throws a general error which is:

General error: 1 near "variation_length": syntax error (SQL: select * from "tests" where "published_at" is not null and "completed_at" is null and "visible" = 1 and start_date = DATE_SUB(NOW(), INTERVAL variation_length DAYS))
filipc's avatar

INTERVAL variation_length DAY

try that

filipc's avatar

also DATE(DATE_SUB(NOW(), INTERVAL variation_length DAY)))

to remove the hour minute second

jjmu15's avatar

This throws a similar error:

 General error: 1 near "variation_length": syntax error (SQL: select * from "tests" where "published_at" is not null and "completed_at" is null and "visible" = 1 and start_date = DATE(DATE_SUB(NOW(), INTERVAL variation_length DAY))))

Would it be possible using some extension of parameter grouping do you know? E.g:

Test::active()->where(function($query)
            {
                $query->where('variation_length', '>', $carbonDate->subDays('VARIATION_LENGTH_VALUE');
            })
            ->get();
filipc's avatar

Either you have a different type of database or you may have one brace too many in the raw part, can you check that? Because i tried it myself and it should work.

$tests = Test::active()->->whereRaw("start_date = DATE(DATE_SUB(NOW(), INTERVAL {{column_name}} DAYS))")
jjmu15's avatar

I can't see any errors in it. My exact code is below:

$tests = Test::active()->whereRaw("start_date = DATE(DATE_SUB(NOW(), INTERVAL variation_length DAY))")->get();

The DB type is InnoDB with UTF-8 Unicode encoding.

I still get the general error as before. Do you see anything obvious?

filipc's avatar

can you try datesub on its own? SELECT DATE_SUB(NOW(), INTERVAL 1 DAY)

jjmu15's avatar

The same error pretty much :(

filipc's avatar

try subdate instead of datesub

SELECT SUBDATE(NOW(), INTERVAL 1 DAY)

jjmu15's avatar
 General error: 1 near "SELECT": syntax error (SQL: select * from "tests" where "published_at" is not null and "completed_at" is null and "visible" = 1 and start_date = SELECT SUBDATE(NOW(), INTERVAL 1 DAY))

Seems like the same kind of error. I'm not sure what the problem is but it seems like a fundamental problem with the subdate function in my db :/

filipc's avatar

hold on I meant trying SELECT on its own so we can figure out what would happen

Do you have mysql workbench or phpmyadmin?

If not then try this

dd(DB::statement("SELECT SUBDATE(NOW(), INTERVAL 1 DAY)"));

filipc's avatar

also try this:

$tests = Test::active()->whereRaw("start_date = DATE(NOW())")->get();

if that passes, try this $tests = Test::active()->whereRaw("start_date = DATE(SUBDATE(NOW(), INTERVAL 1 DAY))")->get();

jjmu15's avatar

Ok so maybe we're getting somehwere.

It seems like it isn't getting access to the raw sql functions.

I entered

$tests = Test::active()->whereRaw("start_date = DATE(NOW())")->get();

and got an error saying the NOW function doesn't exist

General error: 1 no such function: NOW (SQL: select * from "tests" where "published_at" is not null and "completed_at" is null and "visible" = 1 and start_date = DATE(NOW()))

jjmu15's avatar

Nope, MySQL.

Thanks for taking the time to help btw. Much appreciated! :)

jjmu15's avatar

ah... does Laravel use SQL lite when using refresh DB for testing do you know?

I'm using TDD and running the code via the test so that could explain it?!

filipc's avatar

yes, tests are usually run through sqlite

You could extract this logic into its own class, make an interface and then have different implementations for MySQL and SQLite, but this is more advanced.

Else if you don't expect many records for this table, you could try filtering them through PHP

Arushad's avatar

try this, not tested

$now = CarbonImmutable::parse(now())->format('d/m/y');
$tests = Test::active()->where('start_date', '=', $now->subDays('DB_COLUMN_VAL'));
pilat's avatar

whereDate() allows to check for "date (month day) part of your date". Similar methods: whereMonth() and whereYear().

Just use plain old where() in your query: Test::active()->where('start_date', $now->subDays('DB_COLUMN_VAL'));

Snapey's avatar

@arushad @pilat The DB_COL_VAL is another column on the table row - its not something you can manipulate with PHP so neither answer helps.

Arushad's avatar

set DB_COLUMN_VAL to a variable then, replace the 'DB_COLUMN_VAL' with that variable

jjmu15's avatar

@arushad - its not really possible to do that as the DB_COLUMN_VAL will differ per row in the DB and I need to use that value to filter the results.

Please or to participate in this conversation.