How to use LIST_AGG in netsuite - sql

I want to concatenate the result of a column in Netsuite. I tried List_Agg but no luck.
select t.id, LIST_AGG(tn.trackingnumber, ',')
from transaction t
left join trackingnumber tn on
(
INSTR(', '||t.trackingnumberlist||', ', ', '||tn.id||', ') > 0
)
where t.id = 1
Here t.trackingnumberlist = 1,2,3
Any suggestion/alternate of LIST_AGG

I've spoken with NetSuite support about this in the past, and unfortunately, it is not possible. Their ODBC SuiteAnalytics Connect service is based on the SQL-92 standard, rather than any Oracle database standard, thus it does not have this feature, as LIST_AGG was added to Oracle SQL back in 11g in 2007 (14 years ago - https://oracle-base.com/articles/misc/string-aggregation-techniques#listagg).
I've had to resort to performing my own aggregate functions within my C# code after pulling the data over, as SQL-92 is so limited, that it's not possible to even reproduce the function of what LIST_AGG does in that environment.
Sorry to be the bearer of bad news.

I'm not sure about SuiteAnalytics Connect, but I can run the following query in SuiteScript using the N/query.runSuiteQL() function. This is in Netsuite 2022.1.
SELECT
LISTAGG (tranid, ',') WITHIN GROUP(ORDER BY tranid) AS document_numbers,
trandate AS date
FROM
transaction
WHERE
rownum < 10
GROUP BY trandate
It does appear that there is a character limit for each result, so if you are seeing errors, you might try reducing the number of results you are aggregating.

Related

Using date functions in where clause of SQL

My question is regarding particular use case of SQL.
I am trying out querybook and presto type sql for a work project.
I deciphered that while writing SQL queries in querybook - it follows a different style of SQL which is Presto.
I want to write a SQL query which can:
give all entries from a table where the created_at_unix_timestamp > unix_timestamp_of_past_hour
There are some functions like FROM_UNIXTIME and TO_UNIXTIME which I'm experimenting with - but all of these functions are usable in the 1st part of the query
select *
where we describe the fields we want from a table
Is it possible to write a query like this
select *
from table
where to_unixtime(field_in_table) > some_unix_timestamp_value_calculated_at_runtime
I am not able to find any documentation around this.
An update:
when i try this - it's giving an error
Final Update:
It's working with this syntax:
select * from events.table where event_name='some_event_name' and consumer_timestamp > ( CAST(to_unixtime(CAST(LOCALTIMESTAMP AS timestamp)) AS BIGINT) - 3590) order by consumer_timestamp DESC limit 10

Executing a Aggregate function within a case without Group by

I am trying to assign a specific code to a client based on the number of gifts that they have given in the past 6 months using a CASE. I am unable to use WITH (screenshot) due to the limitations of the software that I am creating the query in. It only allows for select functions. I am unsure how to get a distinct count from another table (transaction data) and use that as parameters in the CASE I have currently built (based on my client information table). Does anyone know of any workarounds for this? I am unable to GROUP BY clientID at the end of my query because not all of my columns are aggregate, and I only need to GROUP BY clientID for this particular WHEN statement in the CASE. I have looked into the OVER() clause, but I am needing my date range that I am evaluating to be dynamic (counting transactions over the last six months), and the amount of rows that I would be including is variable, as the transaction count month to month varies. Also, the software that I am building this in does not recognize the PARTITIONED BY parameter of the over clause.
Any help would be great!
EDIT:
it is not letting me attach an image... -____- I have added the two sections of code that I am looking for assistance with!
WITH "6MonthGIftCount" (
"ConstituentID"
,"GiftCount"
)
AS (
SELECT COUNT(DISTINCT "GiftView"."GiftID" FROM "GiftView" WHERE MONTHS_BETWEEN("GiftView"."GiftDate", getdate()) <= 6 GROUP BY "GiftView"."ConstituentID")
SELECT...CASE
WHEN "6MonthGiftCount"."GiftCount" >= 4
THEN 'A010'
)
Perform your grouping/COUNT(1) in a subquery to obtain the total # of donations by ConstituentID, then JOIN this total into your main query that uses this new column to perform its CASE statement.
select
hist.*,
case when timesDonated > 5 then 'gracious donor'
when timesDonated > 3 then 'repeated donor'
when timesDonated >= 1 then 'donor'
else null end as donorCode
from gifthistory hist
left join ( /* your grouping subquery here, pretending to be a new table */
select
personID,
count(1) as timesDonated
from gifthistory i
WHERE abs(months_between(giftDate, sysdate)) <= 6
group by personid ) grp on hist.personid = grp.personID
order by 1;
*Naturally, syntax changes will vary by DB; you didn't specify which it was based on, but you should be able to use this template with whichever you utilize. This works in both Oracle and SQL Server after tweaking the month calculation appropriately.

Oracle returns rows- Crystal reports doesn't

I have a view i've created in Oracle. It returns rows, but when I use it through Crystal Reports, I get no rows. I've narrowed it down to this CTE in the query behind the view:
WITH PERIODS AS (
SELECT
ROWNUM-13 RN,
TO_DATE('01-JUL-' || TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE),-6), 'YYYY')) AS FISCAL_YEAR_START,
ADD_MONTHS(TO_DATE('01-JUL-' || TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE),-6), 'YYYY')), ROWNUM-13) AS MONTH
FROM
DUAL
CONNECT BY
ROWNUM <= 24
)
This is quite weird, as if I replace this CTE with the following, it works (this second query is what the original report had, but due to logical issues in finding the financial year, it had to be changed).
WITH PERIODS AS (
SELECT
ROWNUM-13 RN,
ADD_MONTHS(TRUNC(sysdate,'yyyy'),6) AS FISCAL_YEAR_START,
TRUNC(ADD_MONTHS(ADD_MONTHS(TRUNC(sysdate,'yyyy'),6), ROWNUM-13),'MONTH') MONTH
FROM
DUAL
CONNECT BY
ROWNUM <= 24
)
Any idea why the second CTE causes Crystal reports to not pull any records? There are definitely rows being returned with both queries, just Crystal Reports doesn't like the first query (although I don't understand why as I would have thought Crystal would simply query Oracle for the data, and not be bothered by what is behind the view?!)
Not sure why, but I changed the CTE to the following and it worked:
SELECT
ROWNUM-13 RN,
ADD_MONTHS(TRUNC(ADD_MONTHS(SYSDATE,6),'YYYY'),-6) AS FISCAL_YEAR_START,
ADD_MONTHS(ADD_MONTHS(TRUNC(ADD_MONTHS(SYSDATE,6),'YYYY'),-6), ROWNUM-13) MONTH
FROM
DUAL
CONNECT BY
ROWNUM <= 24
I would still really like to know why the query behind the view was affecting Crystal Reports!
In your first query this line:-
TO_DATE('01-JUL-' || TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE),-6), 'YYYY')) AS FISCAL_YEAR_START
would simplify down to:-
TO_DATE('01-JUL-2012')
Oracle will use the default date format to do the conversion.
Perhaps this is being set differently when you connect via Crystal Reports. It is better practice to explicitly set the date format by providing a second argument to TO_DATE.
Did Crystal Reports report an ORA error, like perhaps ORA-01861: literal does not match format string?

Oracle concatenation of columns with comma [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I combine multiple rows into a comma-delimited list in Oracle?
Could some one please tell me how to achieve the following?
Table:
efforts_id cycle_name release_name
123 quarter march
123 half april
123 full april
124 quarter may
My expected output:
efforts_id cycle_name release_name
123 quarter,half,full march,april
124 quarter may
I am a beginner in oracle so not sure how to do this. Any help would be appreciated.
Thanks
What you need is "string aggregation". Tim Hall's excellent site shows the alternatives you have depending on the exact version of Oracle you have: http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php
In 11gR2 (current at time of writing), you should use the listagg function:
select
efforts_id,
listagg(cycle_name, ',') within group (order by cycle_name) as cycle_name,
listagg(release_name, ',') within group (order by release_name) as release_name
from my_table
group by efforts_id;
Note that the use of the wm_concat function is unsupported by Oracle...
You will want to use LISTAGG() to perform this task. The other answers don't remove any of the duplicate values, to remove the duplicates, you can use something similar to this:
select c.efforts_id,
c.cycle_name,
listagg(r.release_name, ', ') within group (order by c.efforts_id) as release_name
from
(
select efforts_id,
listagg(cycle_name, ', ') within group (order by efforts_id) as cycle_name
from yourtable
group by efforts_id
) c
inner join
(
select distinct efforts_id, release_name
from yourtable
) r
on c.efforts_id = r.efforts_id
group by c.efforts_id, c.cycle_name
See SQL Fiddle with Demo
If you have Oracle 11g R2, then LISTAGG is the preferred way to do it:
SELECT efforts_id,
LISTAGG(cycle_name) WITHIN GROUP(ORDER BY cycle_name),
LISTAGG(release_name) WITHIN GROUP(ORDER BY cycle_name)
FROM MY_TABLE
GROUP BY efforts_id
If not, this article shows the alternative ways of doing it.
Through the WM_concat function (and GROUP BY of course)
SELECT efforts_id, wm_concat(cycle_name), wm_concat(release_name)
FROM MY_TABLE
GROUP BY efforts_id
Hmmm, just found this:
Note that WM_CONCAT is undocumented and unsupported by Oracle, meaning it should not be used in production systems
The LISTAGG function, which can produce the same output as WM_CONCAT is both documented and supported by Oracle.

counting date and time for historical reporting

I am currently working on a query that will be used in junction with share-point to run reports. I have a query that I know will work with Oracle, but the company I am working for is running SQL Server 2005.
What the report will do is give the person the ability to select any date and time, and give the count for that specific operation. The problem is that there are large gaps in the time stamps (because it takes a little while for the product to get to the next operation). The date type is varchar, so i used substrings to parse out the year, month, day, and time. I have sample data available.
The people looking at the reports want the ability to say at this time and day how many units went through this operation.
I know this is is confusing, let me know if you need any clarification.
Here is the oracle syntax
SELECT T3.PAYMENT_DATE, T3."Hr", T3."Min",
(SELECT COUNT(*)
FROM INVOICE_ARCHIVE T4
WHERE TO_NUMBER(TO_CHAR(T4.PAYMENT_DATE, 'MM')) <= T3."Hr"
AND TO_NUMBER(TO_CHAR(T4.PAYMENT_DATE, 'DD')) <= T3."Min") AS "NUM"
FROM(SELECT T1.PAYMENT_DATE, T2."Hr", T2."Min"
FROM (SELECT (FLOOR((LEVEL + 359)/60)) AS "Hr",
MOD((LEVEL + 359), 60) AS "Min"
FROM dual CONNECT BY LEVEL <= 961) T2, INVOICE_ARCHIVE T1
ORDER BY T1.PAYMENT_DATE, T2."Hr", T2."Min") T3
The answer to your question is the datepart() function in SQL Server. This will allow you to extract minutes and hours from dates.
The harder part is the "connect by level" portion. How is this being used? You might need to use recursive CTEs to handle this.
With the little hint from spencer, the following may suffice for your query:
SELECT T3.PAYMENT_DATE, T3."Hr", T3."Min",
(SELECT COUNT(*)
FROM INVOICE_ARCHIVE T4
WHERE datepart(month, T4.PAYMENT_DATE) <= T3."Hr" AND
datepart(day, T4.PAYMENT_DATE, 'DD') <= T3."Min"
) AS "NUM"
FROM (SELECT T1.PAYMENT_DATE, T2."Hr", T2."Min"
FROM (SELECT top 961 (FLOOR((LEVEL + 359)/60)) AS "Hr",
MOD((LEVEL + 359), 60) AS "Min"
FROM (select top 961 row_number() over (order by (select NULL)) as level
from invoice_archive
) t
) T2 cross join
INVOICE_ARCHIVE T1
) T3
ORDER BY T3.PAYMENT_DATE, T3."Hr", T3."Min"
I made the following changes:
Changed the date arithmetic to use datepart() instead of to_char() .
Replaced the method for getting a list of numbers, by using row_number() instead of connect by level
Made the cross join explicit
Moved the order by to the outer query, since neither SQL Server nor Oracle guarantee the results of an order by in a subquery (and SQL Server does not allow it unless you have a "TOP" query)