I have the following query:
// Need a subquery to limit to 1 update
const subQuery = queryBuilder => queryBuilder
.forUpdate()
.where('won', false)
.where('win_after', '<=', knex.fn.now())
.orderBy('priority', 'desc')
.limit(1);
knex('prizes')
.forUpdate()
.where(subQuery)
.update({
won_at: knex.fn.now(),
won: true,
})
.returning('*');
The query I'm trying to buid is
UPDATE
"prizes"
SET
"won_at" = CURRENT_TIMESTAMP,
"won" = $1
WHERE
(
SELECT * FROM "prizes"
WHERE "won" = $2
AND "win_after" <= CURRENT_TIMESTAMP
ORDER BY "priority"
LIMIT 1
)
returning *
I'm trying to find one prize (only 1) to update and mark as one (sorting by prize priority).
The generated query is
update "prizes" set "won_at" = CURRENT_TIMESTAMP, "won" = $1 where ("won" = $2 and "win_after" <= CURRENT_TIMESTAMP) returning * trx4
(See this knex playground link)
So it's missing the ORDER BY and LIMIT. Still a novice with knex and pg, so any help is appreciated!
Initially I was tring to implement CTEs (Common Table Expressions) but after all I managed to do without:
// Need a subquery to limit to 1 update
const subQuery = db<Prize>('prizes')
.select('uuid')
.forUpdate()
.whereNot('won', true)
.where('win_after', '<=', db.fn.now())
.orderBy('priority', 'desc')
.first()
return db<Prize>('prizes')
.transacting(trx)
.where('uuid', subQuery)
.update({
won_at: db.fn.now(),
won: true,
})
.returning('*');
});
Which translates to the following SQL:
update
"prizes"
set
"won_at" = CURRENT_TIMESTAMP,
"won" = true
where
"uuid" = (
select
"uuid"
from
"prizes"
where
not "won" = true
and "win_after" <= CURRENT_TIMESTAMP
order by
"priority" desc
limit
1 for
update
) returning *
Here is the knex playground.
Related
i have a query that goes
select count(id), status, "createdAt"::date from "ProjectLog" where "projectId" = (select id from "Project" where slug = ${id}) and "createdAt" > current_date - interval '${interval} day' group by "createdAt"::date, status;
i've also tried user Prisma.sql to pass the value inside the quotes but it keeps throwing error that it expected 1 argument but fount 2.
i did not have this issue with prisma 2.20.1
this issue is only happening on version 3.3.0
Query: select count(id) as count, status, "createdAt"::date from "ProjectLog" where "projectId" = (select id from "Project" where slug = $1) and "createdAt" > current_date - interval '$2 day' and key notnull group by "createdAt"::date, status
Param: ["main","30"]
PrismaClientKnownRequestError:
Invalid `prisma.queryRaw()` invocation:
Your raw query had an incorrect number of parameters. Expected: `1`, actual: `2`.
code: 'P1016',
clientVersion: '3.3.0',
meta: { expected: 1, actual: 2 }
}
any suggestions ?
i'm not sure if this is a bug.
didn't find an elegant solution in the prism documentation, I couldn't even find one, but there is a way that works...you can try this ${'variable'}
Try to use:
const interval = num + ' days';
${interval}::TEXT::INTERVAL
instead of interval '${interval} day'
This is work for me!
const amIAvailable = (request, response) => {
const { start_date, end_date, my_emp_id } = request.body;
console.log(request.body, 'body')
pool.query(
`
SELECT EXISTS (SELECT me.employee_id from (
select counts.employee_id from
(select e.employee_id, count(e.employee_id) review_count from emp_details_2 e
left join project_allocation pa
on e.employee_id = pa.employee_id
left join project pr
on pa.pid = pr.pid
where pa.project_alloc_status='In Progress' AND pr.start_date NOT BETWEEN $1 AND $2
and pr.end_date NOT BETWEEN $1 AND $2
group by (e.employee_id))
counts
inner join role_allocation ra
on counts.employee_id = ra.employee_id
where counts.review_count <= ra.inclusive_review) me
where me.employee_id = $3)
`, [start_date, end_date, my_emp_id],
(error, results) => {
if (error) {
throw error;
}
response.status(200).json(results.rows);
console.log(results.rows, 'result')
}
);
};
I have written this API which is returning false for particular dates... But when I'm running this same query in pgadmin with same value parameters it's returning true
I'm not able to understand the behavior. Dates are in MM/DD/YYYY format.
Probably the reason is the way that date strings are treated. Replace this query line
and pr.end_date NOT BETWEEN $1 AND $2
with this one (i.e. make string-to-date conversion explicit and controlled)
and pr.end_date NOT BETWEEN to_date($1, 'MM/DD/YYYY') AND to_date($2, 'MM/DD/YYYY')
I would suggest that whenever dates, timestamps, time zones or encodings are concerned you always use explicit settings/rules and never rely on defaults.
I am trying to use .UnionAll method in go-pg library for golang.
var model []Customer
q0 := db.Model(&model).Where("name = ?", name0).Limit(4)
q1 := db.Model(&model).Where("name = ?", name1).Limit(3)
var result []Customer
if err := q0.UnionAll(q1).Limit(1).Select(&result); !as.NoError(err) {
return
}
This code produces the query:
(SELECT "customer"."id", "customer"."name" FROM customers AS "customer" WHERE (name = 'customer 1deificatory zonoid reprepare alacrify serenissime')
LIMIT 1)
UNION ALL
(SELECT "customer"."id", "customer"."name" FROM customers AS "customer" WHERE (name = 'customer 2fordless ferroboron radiability dandizette smutch'
LIMIT 3)
)
But I expect it to be:
(SELECT "customer"."id", "customer"."name" FROM customers AS "customer" WHERE (name = 'customer 1deificatory zonoid reprepare alacrify serenissime')
LIMIT 4)
UNION ALL
(SELECT "customer"."id", "customer"."name" FROM customers AS "customer" WHERE (name = 'customer 2fordless ferroboron radiability dandizette smutch')
LIMIT 3)
LIMIT 1
So how to use go-pg to get raw SQL query which I expect?
The thing is I can't apply the Limit 1 expression to the whole query for some reason.
Also, my Limit 4 is not applied correctly to the first union all member.
My whole code is here.
I believe this query does the trick for you.
if err := db.Model().With("union_q", q0.UnionAll(q1)).Table("union_q").Limit(1).Select(&result); !as.NoError(err) {
return
}
The query isn't exactly what you wanted to be and as far as I know, the current version of go-pg can't generate that query. But this query does exactly what you wanted.
How to convert SQL query to TYPO3 query builder.
SELECT * FROM tableName ORDER BY (CASE WHEN DATE(dateColumn) < DATE(GETDATE()) THEN 1 ELSE 0
END) DESC, dateColumn ASC
enter link description here
Same functionality i need in typo3 query builder.
To get the sql query you posted, you can do it like following:
// little helper function to debug querybuilder,
// queries with parameter placeholders
function debugQuery(QueryBuilder $builder)
{
$preparedStatement = $builder->getSQL();
$parameters = $builder->getParameters();
$stringParams = [];
foreach ($parameters as $key => $parameter) {
$stringParams[':' . $key] = $parameter;
}
return strtr($preparedStatement, $stringParams);
}
// get querybuilder
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionByName('Default')
->createQueryBuilder();
// build query
$queryBuilder
->select('*')
->from('table')
->getConcreteQueryBuilder()->orderBy(
'(CASE WHEN DATE('
.$queryBuilder->quoteIdentifier('dateColumn')
.') < DATE(GETDATE()) THEN 1 ELSE 0 END)',
'DESC'
)
;
$queryBuilder->addOrderBy('dateColumn', 'ASC');
// build query
$sql = debugQuery($queryBuilder);
The generates following sql query:
SELECT
FROM `table`
ORDER BY
(CASE WHEN DATE(`dateColumn`) < DATE(GETDATE()) THEN 1 ELSE 0 END) DESC,
`dateColumn` ASC
Some note beside:
To my knowlage GETDATE() is not a valid mysql method, more MSSQL. Eventually you want CURRENT_DATE() instead.
edit #1
Not tested/run .. just created the sql string to match what you provided. So don't blame me if provided sql query is wrong itself.
SELECT_QUERY = `SELECT * FROM events WHERE c_id = ? AND start_time > ? and
end_time < ?`
query := sr.db.Raw(SELECT_QUERY, request.GetCId(), startTime, endTime)
var v = request.GetVIds()
if len(v) > 0 {
query = query.Where(` v_id IN (?) `, v)
} //Only this block introduces first ) after end_time
var c = request.GetStatus().String()
if len(c) > 0 {
query = query.Where( " status = ? ", c) // this introduces the other opening brace //after AND
}
Following is the query generated and found in logs
SELECT * FROM events WHERE c_id = 1 AND start_time > '2020-04-16 18:42:00' and
end_time < '2020-04-16 18:45:50' ) AND ( v_id IN (1,2)) AND ( status = 'STATUS_MIDDLE_CLASS' ORDER BY start_time DESC LIMIT 5 OFFSET 1
The other solution in stackoverflow and internet article doesn't help.
PS: Is it because I mix db.Raw( ) and query.Where() ?
Changing ? to $1 doesn't fix the issue.
Basically a few things fixed the issue.
1) Mixing Raw and query.Where was one issue.
After making the Raw query to sr.db.Where
2)
SELECT_QUERY = `SELECT * FROM events WHERE c_id = ? AND start_time > ? and
end_time < ?`
already has select * from. And then using query := sr.db.Raw(SELECT_QUERY, request.GetCId(), startTime, endTime) introduces nested select *.
So, changed SELECT_QUERY as follows
SELECT_QUERY = `events WHERE c_id = ? AND start_time > ? and
end_time < ?`
solved the issue.
I found a workaround to the error which I received when I tried to add a timestamp filed in Go/Gorm solution with PostgreSQL equivalent to default: now() which is default: time.Now().Format(time.RFC3339)
I received the error because I use AutoMigrate() to create the tables in PostgreSQL. The one problem I found is when trying to use the default value of a function instead of a string (which one can use for a fixed timestamp).
So I had to go into DataGrid (since I use JetBrains, but you can use any PostgreSQL admin tool like pgAdmin) and manually add the timestamp field with default of now() or merely update the existing field to add the default of now(). Then the error goes away when doing your next build in Go.