Why is this subquery NULL in sequelize? - node.js

for (var i=0; i<req.files.length; i++) {
await sequelize.query(
`INSERT INTO images (path, priority, saleId) VALUES (
"${req.files[i].filename}",
(SELECT max FROM (SELECT MAX(priority)+1 AS max FROM images WHERE saleID = ${req.query.saleId}) AS temp),
${req.query.saleId})`
)
}
I wanna get max value in subquery.
But, this subquery contains the query statement itself, not the value.
and sqlMessage is "Column 'priority' cannot be null".
How can i get max value?
This query working well in MySQL. but, not working in Sequelize.
This is "select * from images" result.
This is error message.

Related

TypeOrm ROW_NUMBER() LeftJoin column does not exist

I'm using typeorm with a postgres database and I have a problem with the result of my query.
I am trying to add a column, position :
.addSelect('ROW_NUMBER() OVER (ORDER BY "votecount" DESC) as "position"')
I get the following error: ERROR [ExceptionsHandler] column "voteCount" does not exist
const queryBuilder = this.serverRepository.createQueryBuilder('server')
.leftJoinAndSelect('server.categories', 'category')
.leftJoin('server.vote', 'vote')
.loadRelationCountAndMap('server.voteCount', 'server.vote')
.addSelect('COUNT(vote.id)', 'votecount')
.addSelect('ROW_NUMBER() OVER (ORDER BY "votecount" DESC) as "position"')
.groupBy('server.id, category.id')
.orderBy('votecount', 'DESC')
.skip(pageOptionsDto.skip)
.take(pageOptionsDto.take)
const { entities } = await queryBuilder.getRawAndEntities();
Would you have an idea of how I can solve the problem to know that today my goal being to bring out a paginated list and know that line 5 of page 2 will be at position 15 if I take 10 per page
Thanks for your help.

Count distinct doesn't work when using OrderBy & join

I have the following query trying to get count of a query:
var testQuery = Db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Where(x => x.IsDeleted == false)
.OrderBy(x => x.ConvertedPrice);
var testCount = Db.Scalar<int>(testQuery.Select<Blog>(x => Sql.CountDistinct(x.Id)));
var results = Db.LoadSelect(testQuery.SelectDistinct());
It gives error:
42803: column "blog.converted_price" must appear in the GROUP BY clause or be used in an aggregate function
Issue seems to be the orderby statement. If I remove it then the error goes away. Why does this stop count distinct working?
I am having to clear orderby on all queries I do like this. Is it supposed to work this way?
Also I just realised count is wrong. Results is 501 unique records and testCount is 538.
What am I doing wrong?
Whenever in doubt with what an OrmLite query is generating, you can use the BeforeExecFilter to inspect the DB command before its executed or to just output the query to the Console you can use:
OrmLiteUtils.PrintSql();
You shouldn't be using OrderBy with aggregate scalar functions like COUNT which is meaningless and will fail in your case because it needs to included the GROUP BY clause for joined table queries.
Your specifically querying for COUNT(DISTINCT Id) if you wanted the row count for the query you can instead use:
var testCount = Db.RowCount(testQuery);
If you wanted to use COUNT(*) instead, you can use:
var testCount = Db.Count(testQuery);

Sequelize adds order by id when using limit and offset with 'group and order by' and 'include' breaking sql

Sequelize query without limit or offset produces this SQL:
SELECT [abc].[abcid],
sum([qty]) AS [abcQty]
FROM [AS_AS_XYZ] AS [xyz]
LEFT OUTER JOIN [AS_AS_ABC] AS [abc] ON [xyz].[abcRef] = [abc].[id]
WHERE [xyz].[aRef] = N'1'
AND [xyz].[bRef] = N'1'
GROUP BY [abc].[abcid]
ORDER BY abcQty DESC
However, when limit or offset is added to the sequelize query, the query get added with another order by clause on xyz.id
SELECT [abc].[abcid],
sum([qty]) AS [abcQty]
FROM [AS_AS_XYZ] AS [xyz]
LEFT OUTER JOIN [AS_AS_ABC] AS [abc] ON [xyz].[abcRef] = [abc].[id]
WHERE [xyz].[aRef] = N'1'
AND [xyz].[bRef] = N'1'
GROUP BY [abc].[abcid]
ORDER BY abcQty DESC, [xyz].[id]
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
causing error:
column xyz.id is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause
whereas the expected result was
SELECT [abc].[abcid],
sum([qty]) AS [abcQty]
FROM [AS_AS_XYZ] AS [xyz]
LEFT OUTER JOIN [AS_AS_ABC] AS [abc] ON [xyz].[abcRef] = [abc].[id]
WHERE [xyz].[aRef] = N'1'
AND [xyz].[bRef] = N'1'
GROUP BY [abc].[abcid]
ORDER BY abcQty DESC
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
which will produce paginated result on the grouped resultset on the abc.abcid.
Is there a way to hint Sequelize not to include the order by clause on xyz.id when adding offset and limit?
Here is the code: (Extracted from larger code, so pardon me if there are typos here or there, but it is pretty much what is there and produces the SQL stated earlier)
let query = {};
query.attributes = [
'abc.abcid',
[sequelize.fn('sum', sequelize.col('qty')), 'abcQty'],
];
query.group = ['abc.abcid'];
query.raw = true;
query.where.aRef = 1;
query.where.bRef = 1;
query.order = sequelize.literal('abcQty DESC');
query.include = [{ model: sequelize.models['abc'], attributes: [] }];
query.limit = 10;
query.offset = 10;
let data= await sequelize.models['xyz'].findAndCountAll(query);

AutoQuery/OrmLite incorrect total value when using joins

I have this autoquery implementation
var q = AutoQuery.CreateQuery(request, base.Request).SelectDistinct();
var results = Db.Select<ProductDto>(q);
return new QueryResponse<ProductDto>
{
Offset = q.Offset.GetValueOrDefault(0),
Total = (int)Db.Count(q),
Results = results
};
The request has some joins:
public class ProductSearchRequest : QueryDb<GardnerRecord, ProductDto>
, ILeftJoin<GardnerRecord, RecordToBicCode>, ILeftJoin<RecordToBicCode, GardnerBicCode>
{
}
The records gets returned correctly but the total is wrong. I can see 40,000 records in database but it tells me there is 90,000. There is multiple RecordToBicCode for each GardnerRecord so it's giving me the number of records multiplied by the number of RecordToBicCode.
How do I match the total to the number of GardnerRecord matching the query?
I am using PostgreSQL so need the count statement to be like
select count(distinct r.id) from gardner_record r etc...
Dores OrmLite have a way to do this?
I tried:
var q2 = q;
q2.SelectExpression = "select count(distinct \"gardner_record\".\"id\")";
q2.OrderByExpression = null;
var count = Db.Select<int>(q2);
But I get object reference not set error.
AutoQuery is returning the correct total count for your query of which has left joins so will naturally return more results then the original source table.
You can perform a Distinct count with:
Total = Db.Scalar<long>(q.Select(x => Sql.CountDistinct(x.Id));

Error in Linq: The text data type cannot be selected as DISTINCT because it is not comparable

I've a problem with LINQ. Basically a third party database that I need to connect to is using the now depreciated text field (I can't change this) and I need to execute a distinct clause in my linq on results that contain this field.
I don't want to do a ToList() before executing the Distinct() as that will result in thousands of records coming back from the database that I don't require and will annoy the client as they get charged for bandwidth usage. I only need the first 15 distinct records.
Anyway query is below:
var query = (from s in db.tSearches
join sc in db.tSearchIndexes on s.GUID equals sc.CPSGUID
join a in db.tAttributes on sc.AttributeGUID equals a.GUID
where s.Notes != null && a.Attribute == "Featured"
select new FeaturedVacancy
{
Id = s.GUID,
DateOpened = s.DateOpened,
Notes = s.Notes
});
return query.Distinct().OrderByDescending(x => x.DateOpened);
I know I can do a subquery to do the same thing as above (tSearches contains unique records) but I'd rather a more straightfoward solution if available as I need to change a number of similar queries throughout the code to get this working.
No answers on how to do this so I went with my first suggestion and retrieved the unique records first from tSearch then constructed a subquery with the non unique records and filtered the search results by this subquery. Answer below:
var query = (from s in db.tSearches
where s.DateClosed == null && s.ConfidentialNotes != null
orderby s.DateOpened descending
select new FeaturedVacancy
{
Id = s.GUID,
Notes = s.ConfidentialNotes
});
/* Now filter by our 'Featured' attribute */
var subQuery = from sc in db.tSearchIndexes
join a in db.tAttributes on sc.AttributeGUID equals a.GUID
where a.Attribute == "Featured"
select sc.CPSGUID;
query = query.Where(x => subQuery.Contains(x.Id));
return query;

Resources