How to use union in DAC loopup? - acumatica

How to use Union in DAC lookup fields?
I want to get all DISTINCT FromUnit and ToUnit data by joining them to show in lookup how may i do this?
for example:
SELECT DISTINCT * FROM (SELECT FromUnit FROM INUnit UNION SELECT ToUnit FROM INUnit) AS UNIT

You can avoid doing an UNION query and instead look for global entries (INUnitType.global) that have from unit == to unit:
[PXDBString(6, IsUnicode = true, InputMask = ">aaaaaa")]
[PXUIField(DisplayName="Test")]
[PXSelector(typeof(Search<INUnit.fromUnit, Where<INUnit.unitType, Equal<INUnitType.global>, And<INUnit.fromUnit, Equal<INUnit.toUnit>>>>), typeof(INUnit.fromUnit))]]]>
Screenshot: https://imgur.com/a/OvY8YSq

Related

How to LOWER elements in postgresql array in SELECT statement to do case insensitive search

Can I lower the elements in an array column like I can a varchar or text column?
SELECT * FROM a_tbl a
WHERE LOWER(%(uw)s) = ANY (a.n_lst) -- how to lower?
OR LOWER(a.x) = LOWER(%(uw)s)
I saw in the documentation that I could use citext as my datatype. I might try to alter my table if there isn't a way to use LOWER
a_tbl
-----
id SERIAL PRIMARY KEY
n_lst TEXT[]
x VARCHAR(50)
You can do like below:
select lower('Jonh') = any(lower(n_lst::text)::text[]) from a_tbl;
How to lowercase postgresql array?
SELECT * FROM a_tbl a
WHERE LOWER(%(uw)s) ILIKE ANY (a.n_lst) -- how to lower?
OR LOWER(a.x) = LOWER(%(uw)s)

Acumatica SQL to BQL - Not In

Good day
I am trying to convert my SQL to BQL but I don't know how to do the NOT IN Statment in BQL. I used NotIn2 with search I am not sure if that is right?
I keep on getting time out issues if I use it so I can't test
SELECT INTran.*,
FROM INTran
JOIN INTranSplit ON INTran.RefNbr = INTranSplit.RefNbr
JOIN InventoryItem ON InventoryItem.InventoryID = INTran.InventoryID
WHERE INTran.LotSerialNbr NOT IN
(
SELECT LotSerialNbr
FROM SOShipLineSplit
)
AND InventoryItem.inventoryCD = 'NIS004';
I am going to use it in a foreach loop with the below:
foreach (INTran item in PXSelectJoin<
INTran,
LeftJoin<INTranSplit,
On<INTranSplit.refNbr, Equal<INTran.refNbr>>,
LeftJoin<InventoryItem,
On< INTran.inventoryID, Equal<InventoryItem.inventoryID>>>>,
Where<INTran.lotSerialNbr, NotIn2<Search<SOShipLineSplit.lotSerialNbr>>,
And<InventoryItem.inventoryCD, Equal<Required<InventoryItem.inventoryCD>>>>
>.Select(Base, "NIS004")){}
Well, you cannot implement NotIn with subselect that easily in BQL. But here is what you can do:
You can alter the select to get the same result using join:
PXSelectJoin<INTran,
InnerJoin<INTranSplit, On<...>,
InnerJoin<InventoryItem, On<...>,
LeftJoin<SOShipLineSplit, On<SOShipLineSplit.lotSerialNbr, Equal<INTran.lotSerialNbr>>>>>,
Where<InventoryItem.inventoryCD, Equal<Required<InventoryItem.inventoryCD>>,
And<SOShipLineSplit.ShipmentNbr, IsNull>>
In that example you will only select lines for which SOShipLineSplit was not found

How to aggregate a field in BQL for complex query

I have a BQL query joining three tables as follows:
foreach (PXResult<GLTran, Branch, xTACOpenSourceDetail> rec in
PXSelectJoin<GLTran,
InnerJoin<Branch,
On<GLTran.branchID, Equal<Branch.branchID>>,
InnerJoin<xTACOpenSourceDetail,
On<Branch.branchCD, Equal<xTACOpenSourceDetail.string03>,
And<xTACOpenSourceDetail.openSourceName, Equal<Constants.openSourceName>,
And<xTACOpenSourceDetail.dataID, Equal<Constants.privateer>>>>>>,
Where<Branch.branchCD, NotEqual<Required<Branch.branchCD>>,
And<GLTran.posted, Equal<True>,
And<GLTran.ledgerID, Equal<Required<GLTran.ledgerID>>,
And<GLTran.tranDate, GreaterEqual<Required<GLTran.tranDate>>>>>>,
OrderBy<Asc<xTACOpenSourceDetail.string01, Asc<GLTran.batchNbr>>>>.Select(Base, osdBranch.String03, ledger.LedgerID, tacsmlm.Date01))
I want to add one aggregated field, namely the sum of the GLTran.CuryDebitAmt grouped by GLTran.BatNbr and Branch.BranchCD.
I can easily do this in SQL using the SUM OVER functionality as follows:
SELECT SUM(GLTran.CuryDebitAmt) OVER (PARTITION BY GLTran.BatchNbr, Branch.BranchCD) as 'BatchTotal'
,GLTran.*
,Branch.*
,xTACOpenSourceDetail.*
FROM GLTran
Inner Join Branch
On GLTran.branchID = Branch.branchID
AND Branch.CompanyID = GLTran.CompanyID
Inner Join xTACOpenSourceDetail
On Branch.branchCD = xTACOpenSourceDetail.string03
And xTACOpenSourceDetail.openSourceName = 'TAC FM Map Company Branch'
And xTACOpenSourceDetail.dataID = 'Privateer'
AND xTACOpenSourceDetail.CompanyID = GLTran.CompanyID
Where Branch.branchCD <> '000 0000'
And GLTran.posted = 1
And GLTran.ledgerID = 6
And GLTran.tranDate >= '08/03/2017'
AND GLTran.CompanyID = 2
Order
By xTACOpenSourceDetail.string01 ASC
,GLTran.batchNbr ASC
...but I have no idea how to add this single summed field in BQL. Any help is appreciated.
You will use a PXSelectGroupBy and in your Aggreate for the BQL indicate which fields will "SUM" their values. Any field not called out will be the MAX value.
If you search SUM< in the Acumatica source you can find plenty of BQL examples. Here is a BQL Example from ARPaymentEntry. Only two (curyAdjdAmt & adjAmt) fields will contain a SUM while all other fields returned will be the MAX.
SOAdjust other = PXSelectGroupBy<SOAdjust,
Where<SOAdjust.voided, Equal<False>,
And<SOAdjust.adjdOrderType, Equal<Required<SOAdjust.adjdOrderType>>,
And<SOAdjust.adjdOrderNbr, Equal<Required<SOAdjust.adjdOrderNbr>>,
And<
Where<SOAdjust.adjgDocType, NotEqual<Required<SOAdjust.adjgDocType>>,
Or<SOAdjust.adjgRefNbr, NotEqual<Required<SOAdjust.adjgRefNbr>>>>>>>>,
Aggregate<GroupBy<SOAdjust.adjdOrderType,
GroupBy<SOAdjust.adjdOrderNbr,
Sum<SOAdjust.curyAdjdAmt,
Sum<SOAdjust.adjAmt>>>>>>.Select(this, adj.AdjdOrderType, adj.AdjdOrderNbr, adj.AdjgDocType, adj.AdjgRefNbr);
Another alternative solution for your question would be to create a PXProjection which could be the sum by group values which you then in your regular select include the projection table vs the base table in your BQL. I don't know the performance benefits vs one or the other - just another option.

SQLAlchemy: Referencing labels in SELECT subqueries

I'm trying to figure out how to replicate the below query in SQLAlchemy
SELECT c.company_id AS company_id,
(SELECT policy_id FROM associative_table at WHERE at.company_id = c.company_id) AS policy_id_ref,
(SELECT `default` FROM policy p WHERE p.policy_id = policy_id_ref) AS `default`,
FROM company c;
Note that this is a stripped down, basic example of what I'm really dealing with. The actual schema supports data and relationship versioning that requires the subqueries to include additional conditions, sorting, and limiting, making it impractical (if not impossible) for them to be joins.
The crux of the problem is in how the second subquery relies on policy_id_ref -- the value obtained from the first subquery. In SQLAlchemy, this is effectively what I have now:
ct = aliased(classes.company)
at = aliased(classes.associative_table)
pt = aliased(classes.policy)
policy_id_ref = session.query(at.policy_id).\
filter(at.company_id == ct.company_id).\
label('policy_id_ref')
policy_default = session.query(pt.default).\
filter(pt.id == 'policy_id_ref').\
label('default')
query = session.query(ct.company_id,policy_id_ref,policy_default)
The pull from the "company" table works fine as does the first subquery that retrieves the "policy_id_ref" column. The problem is the second subquery that has to reference that "policy_id_ref" column. I don't know how to write its filter in such a way that it literally renders "policy_id_ref" in the resulting query, to match the label of the first subquery.
Suggestions?
Thanks in advance
You can write your query as
select(
Companies.company_id,
AssociativeTable.policy_id.label('policy_id_ref'),
Policy.default.label('policy_default'),
).select_from(
Companies,
).join(
AssociativeTable,
AssociativeTable.company_id == Companies.company_id,
).join(
Policy,
AssociativeTable.policy_id == Policy.id
)
but in case you need reference to label from subquery => use literal_column
from sqlalchemy import func, select, literal_column
session.query(
func.array_agg(
literal_column('batch_info'),
JSONB
).label('history')
).select_from(
select(
func.jsonb_build_object(
'batch_id', AccountingQueueBatch.id,
'batch_label', AccountingQueueBatch.label,
).label('batch_info')
).select_from(
AccountingQueueBatch,
)
)

How to sort by sum of field of a relation on sails.js?

I searched a lot about sorting elements by sum of votes (in another model), like I do in SQL here :
SELECT item.* FROM item
LEFT JOIN (
SELECT
vote.item,
SUM(vote.value) AS vote.rating
FROM vote
GROUP BY vote.item
) AS res ON item.id = vote.item
ORDER BY res.rating DESC
Is there a way to do it via waterline methods ?
I think you can't do the left join with simple waterline methods, but you can use the .query method to execute your raw SQL syntax.
Sails MySQL adapter makes sum('field') conflict with sort('field'). It will generate SQL query like:
SELECT SUM(table.field) AS field FROM table ORDER BY table.field;
But I want:
SELECT SUM(table.field) AS field FROM table ORDER BY field;
It same as:
SELECT SUM(table.field) AS f FROM table ORDER BY f;
My solution is using lodash.sortBy() to process results. https://lodash.com/docs/4.16.4#sortBy

Resources