Postgres Query Optimization-Update Query - postgresql

I have below two queries which takes time when there is lot of records in DB like 2000000.The column value in 'Where' clause of both queries are dynamic. Can anyone suggest me to to optimize these in a better way?
UPDATE demo.document_details
SET has_dc = 'Y', l3_validation = 'Y',
validation_remark = CONCAT(validation_remark,
'Deliverychallan also available against this document (Alert)<br>'),
fu_5 = CASE WHEN fu_5 = 'Success'
THEN 'Alert'
ELSE fu_5
END
WHERE document_no = '123'
AND document_date = '2018-09-05'
AND user_gstin = 'gstinid'
AND document_type != 'DELIVERY CHALLAN'
AND has_dc IS NULL;
UPDATE demo.document_details
SET is_exclude = 'Y',
l3_validation = 'Y',
validation_remark = CONCAT(validation_remark,
'Cancelled document (Alert)<br>'),
exclude_reason = 'Cancelled document',
fu_5 = CASE WHEN fu_5 = 'Success'
THEN 'Alert'
ELSE fu_5
END
WHERE id IN (1, 2, 3);

Related

Get custom stock product quantity

I use this code to retrieve product quantity by given id
$stockItem = $objectManager->get('\Magento\CatalogInventory\Model\Stock\StockItemRepository');
$productId = 10858;
$productStock = $stockItem->get($productId);
$productStock->getData();
This code work and return this results
array (
'item_id' => '10858',
'product_id' => '10962',
'stock_id' => '1',
'qty' => '0.0000',
'min_qty' => '0.0000',
...
)
But I need to retrieve information by stock_id = 2 instead of default stock (id: 1)
There's a way to do this, using this code?
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productId = 1;
$StockState = $objectManager->get('\Magento\CatalogInventory\Api\StockStateInterface');
$product_qty = $StockState->getStockQty($productId);

How to update from subquery with query builder?

I'm using Symfony 5, Doctrine, and PostgreSQL.
In some Transaction Repository I'm trying to run the code below:
$queryBuilder = $this->em->createQueryBuilder('tr');
$queryBuilder2 = $this->em->createQueryBuilder('t');
$queryBuilder2->select('t.id', 't.status')
->where(
$queryBuilder->expr()->isNotNull('t.timeoutAt'),
$queryBuilder->expr()->lt('t.timeoutAt', ':timeoutAt'),
$queryBuilder->expr()->in('t.status', ':status')
)->setParameters([
'timeoutAt' => Carbon::now(TimezoneEnum::UTC),
'status' => ['pending', 'done'],
])->getDQL();
$queryBuilder->update()
->set(
't.status',
'CASE WHEN t.status = :statusPending THEN :statusDone ELSE :statusInProgress END'
)
->set('tr.updatedAt', ':updatedAt')
->from($queryBuilder2->getDQL(), 't')
->where('t.id = tr.id')
->setParameters([
'updatedAt' => Carbon::now(TimezoneEnum::UTC),
'statusPending' => 'pending',
'statusDone' => 'done',
'statusInProgress' => 'progress',
]);
After calling $queryBuilder->getQuery()->getResult(); I got an error:
Doctrine\ORM\Query\QueryException : [Syntax Error] line 0, col 37: Error: Expected Doctrine\ORM\Query\Lexer::T_SET, got ','
If to remove ->from($queryBuilder2->getDQL(), 't') error will be fixed, but I need this FROM.
Also $queryBuilder2->getQuery()->getResult() working perfect;
How to correctly put sql of $querybuilder2 to FROM part?
this should be what you want
it will update the status and the updatedAt, for only 'pending' and 'done' transations
the getSingleScalarResult() will let you know how much transactions got updated,
change it as you need
return $this->getEntityManager()
->createQueryBuilder()
->update(Transaction::class, 't')
->set('t.status', 'CASE WHEN t.status = :statusPending THEN :statusDone ELSE :statusInProgress END')
->set('t.updatedAt', ':updatedAt')
->where('t.status IN (:statuses)')
->andWhere('t.timeoutAt is NOT NULL')
->andWhere('t.timeoutAt < :timeoutAt')
->setParameter('statuses', ['pending', 'done'])
->setParameter('updatedAt', Carbon::now(TimezoneEnum::UTC))
->setParameter('statusPending','pending')
->setParameter('statusDone', 'done')
->setParameter('statusInProgress', 'progress')
->setParameter('timeoutAt', Carbon::now(TimezoneEnum::UTC))
->getQuery()
->getSingleScalarResult();

EF Core Filtered Include with Select

Sorry for my English.
I ran into a mistake with EF Core 5.0.9 when is use Filtered Include and Select in same time and i don't know is a bug or feature. :)
return await _dbContext.User
.Where(u => !u.TOROLT)
.Where(u => ids.Contains(u.Id))
.Include(u => u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId))
.Select(u => new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = u.EventUsers.First().Id,
IsCelebrated = u.EventUsers.First().IsCelebrated,
IsEventAdmin = u.EventUsers.First().IsEventAdmin,
IsInviteAccepted = u.EventUsers.First().IsInviteAccepted,
IsInvited = u.EventUsers.First().IsInvited,
})
.ToListAsync();
In this time the first elements is select is not from filtered include just from a normal include. SQL Script from Profiler:
SELECT
[u].[Id],
[u].[FirstName],
[u].[LastName],
(
SELECT TOP(1) [e].[Id]
FROM [dbo].[EventUser] AS [e]
WHERE [u].[Id] = [e].[UserId]) AS [EventUserId],
(
SELECT TOP(1) [e0].[IsCelebrated]
FROM [dbo].[EventUser] AS [e0]
WHERE [u].[Id] = [e0].[UserId]) AS [IsCelebrated],
(
SELECT TOP(1) [e1].[IsEventAdmin]
FROM [dbo].[EventUser] AS [e1]
WHERE [u].[Id] = [e1].[UserId]) AS [IsEventAdmin],
(
SELECT TOP(1) [e2].[IsInviteAccepted]
FROM [dbo].[EventUser] AS [e2]
WHERE [u].[Id] = [e2].[UserId]) AS [IsInviteAccepted],
(
SELECT TOP(1) [e3].[IsInvited]
FROM [dbo].[EventUser] AS [e3]
WHERE [u].[Id] = [e3].[UserId]) AS [IsInvited]
FROM [dbo].[User] AS [u]
WHERE ([u].[TOROLT] <> CAST(1 AS bit))
AND [u].[Id] IN (2, 1, 3, 4, 5)
But if is separate filtered include and select, than it work's fine, but this select complete record and not the part of him from database:
var a = await _dbContext.User
.Where(u => !u.TOROLT)
.Where(u => ids.Contains(u.Id))
.Include(u => u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId))
.ToListAsync();
return a.Select(u => new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = u.EventUsers.First().Id,
IsCelebrated = u.EventUsers.First().IsCelebrated,
IsEventAdmin = u.EventUsers.First().IsEventAdmin,
IsInviteAccepted = u.EventUsers.First().IsInviteAccepted,
IsInvited = u.EventUsers.First().IsInvited,
})
.ToList();
Any idea why is this, and how can i solve solve this?
THX
Include is completely ignored if you have custom projection Select, so your filter will be also ignored. It is not a bug, Include works only when you get whole entity from query.
Anyway consider to rewrite your query:
var query =
from u in _dbContext.User
where !u.TOROLT && ids.Contains(u.Id)
from eu in u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId)
.Take(1)
.DefaultIfEmpty()
select new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = eu.Id,
IsCelebrated = eu.IsCelebrated,
IsEventAdmin = eu.IsEventAdmin,
IsInviteAccepted = eu.IsInviteAccepted,
IsInvited = eu.IsInvited,
};
var result = await query.ToListAsync();

Zend_Db_Select : multiple from clause

Hy,
I have some problem vith Zend_Db_Select.
I have 2 variable : category and city. These 2 variables may have a value or they may be unset.
So I verify:
$status = '`p`.status = 1';
if($catID){
$catSQL = "`p`.parent = {$catID}";
}else{
$catSQL = '1=1';
}
if($city){
$citySQL = "`pm`.`meta_key` = 'oras' and `pm`.`meta_value` = {$city}";
$citySelect = array('pm' => 'postsmeta');
$condCity = "`p`.`ID` = `pm`.`parent_id`";
}else{
$citySQL = '1=1';
$citySelect = NULL;
$condCity = '1=1';
}
Now here is my query:
$select = $db->select()
->from( array('p' => 'posts'))
->from($citySelect)
->where($status)
->where($catSQL)
->where($condCity)
->where($citySQL)
;
The problem is that if city is empty I have something like
$select = $db->select()
->from( array('p' => 'posts'))
->from('')
->where(1=1)
->where(1=1)
->where(1=1)
->where(1=1)
;
The questions is how can I remove from('') from my query if city is empty.
Thank you!
Simply,
$select = $db->select()
->from( array('p' => 'posts'));
if($someConditionIsTrue) {
$select->join($table, $condition);
}
$select->where('field_value = ?', 'value1');
if($someConditionIsTrue) {
$select->where('another_field = ?', 'value 2');
}
Hope it helps.
Please use this syntax $select->where('another_field = ?', 'value 2'); for proper escaping values to prevent SQL injections.

how to use joins in Zend_Paginator_Adapter_DbSelect()

how can i replace below mysql query to ZF Zend_Paginator_Adapter_DbSelect()
query
$sql = "SELECT ps.phone_service_id,ps.phone_service_name,ps.phone_service_Duration,ps.phone_service_type,us.user_preferences_value,ps.user_id FROM phone_service ps,user_preferences us
WHERE us.phone_service_id = ps.phone_service_id
AND us.user_preferences_name = 'is_user_package_active'
AND ps.user_id =".$user_id;
i write this one but error occur could you please replace my query to equailent Zend_Paginator_Adapter_DbSelect()
$select = $DB->select()
->from(array('ps' => 'phone_service'
'us' => 'user_preferences'),
array('ps.phone_service_id', 'ps.phone_service_name','ps.phone_service_Duration','ps.phone_service_type','us.user_preferences_value')),
->where('us.phone_service_id = ?', 'ps.phone_service_id')
->where( 'us.user_preferences_name = ?', 'is_user_package_active')
->where( 'us.user_id = ?', $user_id)
;
I guess you want something like this:
$sel = $db->select();
$sel->from(array('p' => 'phone_service'))
->join(array('u' => 'user_preferences'), 'u.phone_service_id = p.phone_service_id')
->where('u.user_preferences_name = ?', 'is_user_package_active')
->where('p.user_id = ?', $user_id);