SuiteQL cannot includes keyword 'DISTINCT'? - sql

I keep on getting an error when I try to use the distinct keyword with SuiteQL.
This is my code:
var bannedItemIdArr = [];
var querySQL = "SELECT DISTINCT item.ID AS idRAW /*{id#RAW}*/ FROM item, (SELECT itemMember.parentitem AS parentitem, itemMember.parentitem AS parentitem_join, itemMember.ID AS ID, item_0.itemtype AS itemtype, itemMember.item AS item, item_0.itemtype AS itemtype_crit, item_0.isinactive AS isinactive_crit FROM itemMember, item item_0 WHERE itemMember.item = item_0.ID(+)) itemMember_SUB WHERE item.ID = itemMember_SUB.parentitem(+) AND ((UPPER(item.itemtype) IN ('ASSEMBLY') AND UPPER(itemMember_SUB.itemtype_crit) IN ('INVTPART', 'ASSEMBLY') AND itemMember_SUB.isinactive_crit = 'T' AND NVL(item.isinactive, 'F') = 'F'))";
var myPagedResults = query.runSuiteQLPaged({ query: querySQL, pageSize: 1000, });
The error:
Search error occurred: Invalid or unsupported search
How can I solve this error?

So the trick here is to use group by and not distinct.
e.g.,
select item.id
from item
group by item.id
That said your query looks like it is using the old oracle-specific syntax for joins (using (+)) instead of the suite-ql supported ANSI92 syntax of left join and right join. Also, you will have to change nvl to use the ANSI92 coalesce.

Have you looked at query.Aggregate?
Enum Description
Module
Holds the string values for aggregate functions supported with the N/query Module. An aggregate function performs a calculation on the column or condition values and returns a single value. Each value in this enum (except MEDIAN) has two variants: distinct (using the _DISTINCT suffix) and nondistinct (using no suffix). The variant determines whether the aggregate function operates on all instances of duplicate values or on just a single instance of the value. For example, consider a situation in which the MAXIMUM aggregate function is used to determine the maximum of a set of values. When using the distinct variant (MAXIMUM_DISTINCT), the aggregate function considers each instance of duplicate values. So if the set of values includes three distinct values that are all equal and all represent the maximum value in the set, the aggregate function lists all three instances. When using the nondistinct variant (MAXIMUM), only one instance of the maximum value is listed, regardless of the number of instances of that maximum value in the set. This enum is used to pass the aggregate function argument to Component.createColumn(options), Component.createCondition(options), Query.createColumn(options), and Query.createCondition(options).
N/query Module
Values
Value
Description
AVERAGE
Calculates the average value.
AVERAGE_DISTINCT
Calculates the average distinct value.
COUNT
Counts the number of results.
COUNT_DISTINCT
Counts the number of distinct results.
MAXIMUM
Determines the maximum value. If the values are dates, the most recent date is determined.
MAXIMUM_DISTINCT
Determines the maximum distinct value. If the values are dates, the most recent date is determined.
MEDIAN
Calculates the median value
MINIMUM
Determines the minimum value. If the values are dates, the earliest date is determined.
MINIMUM_DISTINCT
Determines the minimum distinct value. If the values are dates, the earliest date is determined.
SUM
Adds all values.
SUM_DISTINCT
Adds all distinct values.
Syntax
// Add additional code
...
var myTransactionQuery = query.create({
type: query.Type.TRANSACTION
});
var myAggColumn = myTransactionQuery.createColumn({
fieldId: 'amount',
aggregate: query.Aggregate.AVERAGE
});
myTransactionQuery.columns = [myAggColumn];
...
// Add additional code

Related

function to sum all first value of Results SQL

I have a table with "Number", "Name" and "Result" Column. Result is a 2D text Array and I need to create a Column with the name "Average" that sum all first values of Result Array and divide by 2, can somebody help me Pls, I must use the create function for this. Its look like this:
Table1
Number
Name
Result
Average
01
Kevin
{{2.0,10},{3.0,50}}
2.5
02
Max
{{1.0,10},{4.0,30},{5.0,20}}
5.0
Average = ((2.0+3.0)/2) = 2.5
= ((1.0+4.0+5.0)/2) = 5.0
First of all: You should always avoid storing arrays in the table (or generate them in a subquery if not extremely necessary). Normalize it, it makes life much easier in nearly every single use case.
Second: You should avoid more-dimensional arrays. The are very hard to handle. See Unnest array by one level
However, in your special case you could do something like this:
demo:db<>fiddle
SELECT
number,
name,
SUM(value) FILTER (WHERE idx % 2 = 1) / 2 -- 2
FROM mytable,
unnest(avg_result) WITH ORDINALITY as elements(value, idx) -- 1
GROUP BY number, name
unnest() expands the array elements into one element per record. But this is not an one-level expand: It expand ALL elements in depth. To keep track of your elements, you could add an index using WITH ORDINALITY.
Because you have nested two-elemented arrays, the unnested data can be used as follows: You want to sum all first of two elements, which is every second (the odd ones) element. Using the FILTER clause in the aggregation helps you to aggregate only exact these elements.
However: If that's was a result of a subquery, you should think about doing the operation BEFORE array aggregation (if this is really necessary). This makes things easier.
Assumptions:
number column is Primary key.
result column is text or varchar type
Here are the steps for your requirements:
Add the column in your table using following query (you can skip this step if column is already added)
alter table table1 add column average decimal;
Update the calculated value by using below query:
update table1 t1
set average = t2.value_
from
(
select
number,
sum(t::decimal)/2 as value_
from table1
cross join lateral unnest((result::text[][])[1:999][1]) as t
group by 1
) t2
where t1.number=t2.number
Explanation: Here unnest((result::text[][])[1:999][1]) will return the first value of each child array (considering you can have up to 999 child arrays in your 2D array. You can increase or decrease it as per your requirement)
DEMO
Now you can create your function as per your requirement with above query.

SQL - Loop through a list and add to a variable using sql select statements

I have data loaded in a table called Trades. Now I need to query this table, find elements that satisfy a particular condition and produce the trade value amount.
Here is the requirement
TradeAmt = 0
Loop for all Trades
{IF TradeId is 35
If type = 'I'
ADD (TradeAmt =TradeAmt + col_TradeAmt )
else
ADD (TradeAmt = TradeAmt + col_TradeAmtOverlap )
END-IF}
Return TradeAmt
Data:
Row1: tradeid=35, type=I, col_TradeAmt=10, col_TradeAmtOverlap=20
Row2: tradeid=35, type=S, col_TradeAmt=30, col_TradeAmtOverlap=40
Output: TradeAmt=50
How can i write this using SQL statements.
Well, in SQL you don't really loop over a sequence.
You write a statement that describes what you want to get from the set of data (e.g. the Trades table).
In your case, you want to accumulate all the elements in some way and provide that accumulation as a result, you can do that by using an aggregate function like SUM.
Something along these lines probably could work. Note that I'm nesting two queries here, the inner one to decide which column to treat as the "Amount" to accumulate depending on the Type of the trade and also to filter only the trade with Id 35, and the outer query performs the sum aggregate of all amounts:
SELECT SUM("Amount") FROM
(SELECT
CASE
WHEN Type = 'I' THEN col_TradeAmt
ELSE col_TradeAmtOverlap
END "Amount"
FROM Trades
WHERE TradeId = 35) "TradeAmt";

What is MAX(DISTINCT x) in SQL?

I just stumbled over jOOQ's maxDistinct SQL aggregation function.
What does MAX(DISTINCT x) do different from just MAX(x) ?
maxDistinct and minDistinct were defined in order to keep consistency with the other aggregate functions where having a distinct option actually makes a difference (e.g., countDistinct, sumDistinct).
Since the maximum (or minimum) calculated between the distinct values of a dataset is mathematically equivalent with the simple maximum (or minimum) of the same set, these function are essentially redundant.
In short, there will be no difference. In case of MySQL, it's even stated in manual page:
Returns the maximum value of expr. MAX() may take a string argument;
in such cases, it returns the maximum string value. See Section 8.5.3,
“How MySQL Uses Indexes”. The DISTINCT keyword can be used to find the
maximum of the distinct values of expr, however, this produces the
same result as omitting DISTINCT.
The reason why it's possible - is because to keep compatibility with other platforms. Internally, there will be no difference - MySQL will just omit influence of DISTINCT. It will not try to do something with set of rows (i.e. produce distinct set first). For indexed columns it will be Select tables optimized away (thus reading one value from index, not a table), for non-indexed - full scan.
If i'm not wrong there are no difference
For Columns
ID
1
2
2
3
3
4
5
5
The OUTPUT for both quires are same 5
MAX(DISTINCT x)
// ID = 1,2,2,3,3,4,5,5
// DISTINCT = 1,2,3,4,5
// MAX = 5
// 1 row
and for
MAX(x)
// ID = 1,2,2,3,3,4,5,5
// MAX = 5
// 1 row
Theoretically, DISTINCT x ensures that every element is different from a certain set. The max operator selects the highest value from a set. In plain SQL there should be no difference between both.

Dividing tied RANKs using MDX

Still getting the hang of interpreting the MDX documentation on MSDN. So for the RANK function it has the following:
If a numeric expression is specified, the Rank function determines the
one-based rank for the specified tuple by evaluating the specified
numeric expression against the tuple. If a numeric expression is
specified, the Rank function assigns the same rank to tuples with
duplicate values in the set. This assignment of the same rank to
duplicate values affects the ranks of subsequent tuples in the set.
For example, a set consists of the following tuples, {(a,b), (e,f),
(c,d)}. The tuple (a,b) has the same value as the tuple (c,d). If the
tuple (a,b) has a rank of 1, then both (a,b) and (c,d) would have a
rank of 1. However, the tuple (e,f) would have a rank of 3. There
could be no tuple in this set with a rank of 2. If a numeric
expression is not specified, the Rank function returns the one-based
ordinal position of the specified tuple. The Rank function does not
order the set.
In the following script if two people are tied second for the highest salary I get the following salary ranks:
1
2
2
4
What I'd like to do is use the number of years in service to decide which of the tied people has the higher rank. Is this possible?
WITH
SET [OrderedPeople] AS
ORDER(
NONEMPTY(
[PeopleDimension].[PeopleHier].[NamesLevel].members,
{ //following means if one or the other is null
//then the row is not excluded
[Measures].[Salary],
[Measures].[NumYearsService]
}
),
[Measures].[Salary]
*
[Measures].[NumYearsService]
,
BDESC
)
MEMBER [Measures].[Salary_Rank] AS
RANK([PeopleDimension].[PeopleHier].CurrentMember,
[OrderedPeople],
[Measures].[Salary] //<<<how do I use numYearsService to decide ties?
)
SELECT
NON EMPTY
{
[Measures].[NumYearsService],
[Measures].[Salary],
[Measures].[Salary_Rank]
}
ON COLUMNS,
NON EMPTY
[OrderedPeople]
ON ROWS
FROM [ourCube]
WHERE
(
{TAIL([Date].[Date - Calendar Month].[Calendar Day],7)(0):
TAIL([Date].[Date - Calendar Month].[Calendar Day],7)(6)}
)
If you have the set already ordered, you use Rank without the third argument, i. e.
RANK([PeopleDimension].[PeopleHier].CurrentMember,
[OrderedPeople]
)
Rank returns the position that the first argument has in the set which is the second argument. The third argument is specifically used for the case when you want to have ties getting the same value. If you use the third argument, then for adjacent elements within the set, the third argument is checked, and the return value is the position of the first element within the set that has the same value for the third argument.
To order by several criteria in MDX, nest two orders within each other:
ORDER(
ORDER(
NONEMPTY(
[PeopleDimension].[PeopleHier].[NamesLevel].members,
{ //following means if one or the other is null
//then the row is not excluded
[Measures].[Salary],
[Measures].[NumYearsService]
}
),
[Measures].[NumYearsService]
,
BDESC
),
[Measures].[Salary],
BDESC
)
AS MDX Order is guaranteed to do a stable sort, when executing the outer sort, then the members that have the same salary do not change their relative order from the first sort, which means they keep being sorted by years in service.

How to get MAX Values using the Having Clause in MS Access

I have a Column(Fields) that contain multiple values for each entity (One to Many).
Example: A record can can reference multiple values in this column.
What I want to do is get only records where highest(MAX) value in this column is equals zero.
The first thing I did was convert the values in the column to Integer, this way I can get the Max Value.
Here is my Code:
How do I get the Max code? If a record has more than one code. I want only record with the Max or highest code of 00000.
I am getting an error with the Having clause since I cannot use Aggregate in the Where Clause.
SELECT CUSTOMER.USER_ID, MAX(CInt(CUSTOMER.REC_CODE)) AS ACTIVE_REC_CODE,
CUSTOMER.CUS_TYPE
FROM CUSTOMER
WHERE ((CUSTOMER.REC_CODE) IS NOT NULL )
GROUP BY
CUSTOMER.USER_ID, CUSTOMER.REC_CODE, CUSTOMER.CUS_TYPE
HAVING MAX(CInt([CUSTOMER.REC_CODE])= 00000 )
You are close, but you need to remove CUSTOMER.REC_CODE from your WHERE, since you want the max value of that column. This should work:
SELECT CUSTOMER.USER_ID, MAX(CInt(CUSTOMER.REC_CODE)) AS ACTIVE_REC_CODE, CUSTOMER.CUS_TYPE
FROM CUSTOMER
WHERE CUSTOMER.REC_CODE IS NOT NULL
GROUP BY CUSTOMER.USER_ID, CUSTOMER.CUS_TYPE
HAVING MAX(CInt([CUSTOMER.REC_CODE])) = 0