Using coalesce with sequelize on node.js - mysql

I have the following query:
select coalesce(round(sum(vdamesatual) /
(select count(*)
from feriados
where month(data)=month(current_date) and
day(data)<day(current_date) and
diadasemana in(2,3,4,5,6) and
feriadonacional=0 and
uf <> (select distinct uforigem from baseprodutos where Empresa = 'test'))
*
(select count(*)
from feriados
where month(data)=month(current_date) and
day(data)>=day(current_date) and
diadasemana in(2,3,4,5,6) and
feriadonacional=0 and
uf <> (select distinct uforigem from baseprodutos where Empresa = 'test'))),0) as projecao
from baseprodutos
where Empresa = 'test' and
UFDest = 'uf' and
Fabricante = 'sample';
As you can see I have a coalesce right after the first select, and I am having trouble finding the right way to write this with sequelize; Would you have some suggestion?

I don't really follow the logic of your query, but the rule in Sequelize is that you can call any function with sequelize.fn() so a simple example of using COALESCE in Sequelize to get a value from 2 columns with an alias would be like this in your attributes:
[[sequelize.fn('COALESCE', mysql.col('col_name'), mysql.col('col_2_name')), 'alias'], 'another_col']
You can include another function if needed, like SUM by doing like this:
[[sequelize.fn('COALESCE', sequelize.fn('SUM', (mysql.col('col_name'), mysql.col('col_2_name'))), (some other code here ...)),'alias']]

Related

SqlAlchemy puts SELECT Subquery in FROM clause instead of SELECT

My target SQL is the following, which is valid,
SELECT a.agreement_group_id,
(select id from agreement_t where agreement_group_id = a.agreement_group_id and
active = 'Y'),
...
FROM ets.agreement_t a
WHERE requester_uniqueidentifier = '0010079170'
GROUP BY a.agreement_group_id
ORDER BY a.agreement_group_id
But SqlAlchemy is producing the following -- and complaining that I don't have anon_1 in GROUP BY due to its placement of the sub-select in FROM,
SELECT agreement_t_1.agreement_group_id AS agreement_t_1_agreement_group_id,
anon_1.id AS anon_1_id,
...
FROM ets.agreement_t AS agreement_t_1,
(SELECT ets.agreement_t.id AS id
FROM ets.agreement_t, ets.agreement_t AS agreement_t_1
WHERE ets.agreement_t.agreement_group_id = agreement_t_1.agreement_group_id AND
ets.agreement_t.active = 'Y') AS anon_1
WHERE agreement_t_1.requester_uniqueidentifier = '0010079170'
GROUP BY agreement_t_1.agreement_group_id, anon_1.id
ORDER BY agreement_t_1.agreement_group_id
Python SqlAlchemy code:
agreement = aliased(AgreementT)
subqueryActive = db_session.query(AgreementT.id).filter(
(AgreementT.agreement_group_id == agreement.agreement_group_id),
(AgreementT.active == 'Y')
).subquery()
result = (db_session.query(
agreement.agreement_group_id,
subqueryActive,
...
.filter(*filters)
.group_by(agreement.agreement_group_id)
.order_by(agreement.agreement_group_id)
.all())
I don't need any other Joins. As you can see, the subquery subqueryActive already references the alias agreement which is used in the main query. So why is the Sub-Select not placed properly in the SELECT, but rather in the FROM, with the following error?
psycopg2.errors.GroupingError: column "anon_1.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...ent_group_id AS agreement_t_1_agreement_group_id, anon_1.id ...
^
If the sub-Select should be part of the SELECT, we can't use .subquery(), we need to use .label() instead.
Example here: https://stackoverflow.com/a/43655840/1005607
Thanks for the tip #Ilja Everilä

SET invalid use of group function using AVG

I want to declare a variable called average, what should be the average of the completiondate-creationdate of the items in the todolist.
however, if I use these lines of code, mysql tells me that I have an error in my syntax.
Can somebody tell me what I should change to store the correct value in #average?
SET #average = AVG(todoitem.completiondate-todoitem.creationdate) from todolist
right join todoitem on todoitem.id=todolist.id
;
SELECT name FROM todolist
right join todoitem on todoitem.id=todolist.id
WHERE (todoitem.completiondate-todoitem.creationdate > average)
;
You are missing a select in the first query:
select #average := AVG(todoitem.completiondate - todoitem.creationdate)
from todolist right join
todoitem
on todoitem.id = todolist.id;
Although I'm leaving it in, the join seems unnecessary. Why are you doing the join if you are using only one table?
select #average := AVG(todoitem.completiondate - todoitem.creationdate)
from todoitem;
You have to add SELECT:
SET #average = (SELECT AVG(todoitem.completiondate-todoitem.creationdate))
from todolist
right join todoitem on todoitem.id=todolist.id
-- or
SELECT AVG(todoitem.completiondate-todoitem.creationdate) INTO #average
from todolist
right join todoitem on todoitem.id=todolist.id

Excluding a value from the return result of MySQL

I'm facing a problem and I'm not finding the answer. I'm querying a MySql table during my java process and I would like to exclude some rows from the return of my query.
Here is the query:
SELECT
o.offer_id,
o.external_cat,
o.cat,
o.shop,
o.item_id,
oa.value
FROM
offer AS o,
offerattributes AS oa
WHERE
o.offer_id = oa.offer_id
AND (cat = 1200000 OR cat = 12050200
OR cat = 13020304
OR cat = 3041400
OR cat = 3041402)
AND (oa.attribute_id = 'status_live_unattached_pregen'
OR oa.attribute_id = 'status_live_attached_pregen'
OR oa.attribute_id = 'status_dead_offer_getter'
OR oa.attribute_id = 'most_recent_status')
AND (oa.value = 'OK'
OR oa.value='status_live_unattached_pregen'
OR oa.value='status_live_attached_pregen'
OR oa.value='status_dead_offer_getter')
The trick here is that I need the value to be 'OK' in order to continue my process but I don't need mysql to return it in its response, I only need the other values to be returned, for the moment its returning two rows by query, one with the 'OK' value and another with one of the other values.
I would like the return value to be like this:
'000005261383370', '10020578', '1200000', '562', '1000000_157795705', 'status_live_attached_pregen'
for my query, but it returns:
'000005261383370', '10020578', '1200000', '562', '1000000_157795705', 'OK'
'000005261383370', '10020578', '1200000', '562', '1000000_157795705', 'status_live_attached_pregen'
Some help would really be appreciated.
Thank you !
You can solve this with an INNER JOIN on the self I think:
SELECT o.offer_id
,o.external_cat
,o.cat
,o.shop
,o.item_id
,oa.value
FROM offer AS o
INNER JOIN offerattributes AS oa
ON o.offer_id = oa.offer_id
INNER JOIN offerattributes AS oaOK
ON oaOK.offer_id = oa.offer_id
AND oaOK.value = 'OK'
WHERE o.cat IN (1200000,12050200,13020304,3041400,3041402)
AND oa.attribute_id IN ('status_live_unattached_pregen','status_live_attached_pregen','status_dead_offer_getter','most_recent_status')
AND oa.value IN ('status_live_unattached_pregen','status_live_attached_pregen','status_dead_offer_getter');
By doing a self-JOIN with the restriction of value OK, it will limit the result set to offer_ids that have an OK response, but the WHERE clause will still retrieve the values you need. Based on your description, I think this is what you were looking for.
I also converted your implicit cross JOIN to an explicit INNER JOIN, as well as changed your ORs to IN, should be more performant this way.

Comparing dates in iif() in SQL Server

I am trying to use the following query in SQL Server
SELECT [AL].[Subscriptions].Id,
[AL].[Subscriptions].name,
[AL].[Subscriptions].description,
[AL].[Subscriptions].price,
[AL].[Subscriptions].iconFileName,
IIf(a.expiryDate > Now(), 'TRUE', 'FALSE') AS isSubsByUser
FROM [AL].[Subscriptions]
LEFT JOIN (SELECT *
FROM [AL].[UserSubscriptions]
WHERE userId = 13259) AS a
ON Subscriptions.Id = a.itemid;
but always get the error
Error in list of function arguments: '>' not recognized.
Unable to parse query text.
How do I resolve it?
Like Martin Smith said you need to use a case statement. Also it looks like you are only using a couple of fields in the derived table therefor I would suggest not using *. I put a example below.
SELECT [AL].[Subscriptions].Id,
[AL].[Subscriptions].name,
[AL].[Subscriptions].description,
[AL].[Subscriptions].price,
[AL].[Subscriptions].iconFileName,
case when a.expiryDate > GetDate() then 'TRUE' else 'FALSE' end AS isSubsByUser
FROM [AL].[Subscriptions]
LEFT JOIN (SELECT expiryDate, itemid
FROM [AL].[UserSubscriptions]
WHERE userId = 13259) AS a
ON Subscriptions.Id = a.itemid;

error in mysql query - inner join inside where

i got this error:
for the right syntax to use near 'INNER JOIN oferta B ON A.oferta_id_oferta = B.id_oferta AND B.oferta = "design' at line 4
i can't make a inner join inside a where clause ? or exists other problem with this query ?
UPDATE `oferta_has_tags` A
SET fraccao = "1/7"
WHERE (
INNER JOIN oferta B
ON A.oferta_id_oferta = B.id_oferta
AND B.oferta = "designer"
AND B.estado = 0)
Express it as a simple IN:
UPDATE oferta_has_tags
SET fraccao = '1/7'
WHERE oferta_id_oferta IN (
SELECT id_oferta
FROM oferta
WHERE oferta = 'designer'
AND estado = 0)
Also, changed double quotes (") to single quotes (') - using double quotes will cause an error
The query is wrong. It must have SELECT and FROM clauses:
It must be something like this:
UPDATE oferta_has_tags A
SET fraccao = "1/7"
WHERE id = ( SELECT id FROM yourtable WHERE something = somevalue )
Make sure that the subquery should return exactly 1 value. If you want to update multiple records using above query, replace "=" with "IN". Like this:
UPDATE oferta_has_tags A
SET fraccao = "1/7"
WHERE id IN ( SELECT id FROM yourtable WHERE something = somevalue )
Hope it helps...