Invalid Number with date filter in Oracle SQL where clause - sql

Using Oracle SQL, I am getting this error with my query:
ORA-01722: invalid number
01722. 00000 - "invalid number"
I am using two tables to get a maximum date and min date from a transaction table for requests. Without the line "AND mgr_min.create_date > to_date('01-01-15', 'MM-DD-YY')" it seems to return the results I need. But when I try to filter based on date that a request was created...I get the error. Here is the query:
SELECT mr.accessor_id,
mrs.status_description,
mso.option_name,
CAST(mgr_max.create_date AS TIMESTAMP) AS "Action Date",
mgr_max.detail_comment AS "Comment",
mgr_min.create_date AS "Date Created"
FROM moca_request mr,
moca_request_status mrs,
moca_system_option mso,
moca_system ms,
(SELECT mrt.request_id, mrt.status_id, mrt.approver_id, mrt.create_date, mrt.detail_comment
FROM moca_request_transaction mrt
INNER JOIN (
SELECT request_id, MAX(create_date) AS maxdate
FROM moca_request_transaction
GROUP BY request_id) mrt2
ON mrt.request_id = mrt2.request_id AND mrt.create_date = mrt2.maxdate) mgr_max,
(SELECT mrt3.create_date, mrt3.request_id
FROM moca_request_transaction mrt3
INNER JOIN (
SELECT request_id, MIN(create_date) AS createdate
FROM moca_request_transaction
GROUP BY request_id) mrt4
ON mrt3.request_id = mrt4.request_id AND mrt3.create_date = mrt4.createdate) mgr_min
WHERE mgr_max.request_id = mr.request_id
AND mgr_max.status_id = mrs.status_id
AND mgr_min.request_id = mr.request_id
AND mso.option_id = mr.option_id
AND ms.system_id = mr.system_id
AND mgr_min.create_date > to_date('01-01-15', 'MM-DD-YY')

Related

Get a cumulative sum in SQL

I am struggling with a postgresql query where I am trying to get the cumulative sum instead of the sum, by date truncated.
Here is my original query
SELECT date_trunc('month', "public"."stock_transaction"."created_at") AS "created_at", "Category"."name" AS "Category - name", sum("public"."stock_transaction"."cost") AS "sum"
FROM "public"."stock_transaction"
LEFT JOIN "public"."product" "Product" ON "public"."stock_transaction"."product_id" = "Product"."id" LEFT JOIN "public"."category" "Category" ON "Product"."category_id" = "Category"."id"
WHERE ("public"."stock_transaction"."owner_id" = {{organization.id}}::uuid
AND {{createdAt}}
AND "Product"."recipe" = FALSE)
GROUP BY date_trunc('month', "public"."stock_transaction"."created_at"), "Category"."name"
ORDER BY date_trunc('month', "public"."stock_transaction"."created_at") ASC, "Category"."name" ASC
and it looks like this
It's generated by metabase. createdAt is a date field filter and organizationId an uuid.
The result should be an increasing bar chart with the value of each month added to the previous month.
I have tried with subqueries but I have a hard time solving every SQL error I jump into.
Is there a SQL boss around who can help? Thanks :D
you just need a window function to get a cumulative sum :
SELECT s."created_at"
, s."Category - name"
, sum(s."sum") OVER (PARTITION BY s."created_at", s."Category - name" ORDER BY s."created_at" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS "sum"
FROM (
SELECT date_trunc('month', "public"."stock_transaction"."created_at") AS "created_at", "Category"."name" AS "Category - name", sum("public"."stock_transaction"."cost") AS "sum"
FROM "public"."stock_transaction"
LEFT JOIN "public"."product" "Product" ON "public"."stock_transaction"."product_id" = "Product"."id"
LEFT JOIN "public"."category" "Category" ON "Product"."category_id" = "Category"."id"
WHERE ("public"."stock_transaction"."owner_id" = {{organization.id}}::uuid
AND {{createdAt}}
AND "Product"."recipe" = FALSE)
GROUP BY date_trunc('month', "public"."stock_transaction"."created_at"), "Category"."name"
-- ORDER BY date_trunc('month', "public"."stock_transaction"."created_at") ASC, "Category"."name" ASC -- not needed here
) AS s
ORDER BY s."created_at"

Filter rows using on conditions twice the same column

I have the next query:
select CHANNEL , my_date
from table_1 d
where source_data = 'test_5'
and my_date < to_date('27/09/2020','DD/MM/YYYY')
and customer_ID = :param_customer_ID
order by d.my_date asc;
That will show the next result:
My need is. have the last vale filter for the last my_date, grouping by channel. My result for this example must look like this:
Just the two rows.
I tried with:
select CHANNEL , my_date
from table_1 d
where source_data = 'test_5'
and (my_date < to_date('27/09/2020','DD/MM/YYYY') and my_date = max(my_date))
and customer_ID = :param_customer_ID
group by CHANNEL, my_date
order by d.my_date asc;
but nothing, it doesn't work, and give me error
ORA-00934: función de grupo no permitida aquí
00934. 00000 - "group function is not allowed here"
*Cause:
*Action:
Error en la línea: 138, columna: 30
what should i do?
Regards
In Oracle, you can use aggregation:
select channel, max(my_date)
from table_1 d
where source_data = 'test_5' and
my_date < date '2020-09-27' and
customer_ID = :param_customer_ID
group by channel;
If there are more columns that you want, then use row_number():
select channel, my_date
from (select d.*,
row_number() over (partition by channel order by my_date desc) as seqnum
from table_1 d
where source_data = 'test_5' and
my_date < date '2020-09-27' and
customer_ID = :param_customer_ID
) d
where seqnum = 1;

Trying to join two tables via subquery

Current query below
select
x.OVERALL_ID,
extract(year from y.tsdate) as year,
extract(month from y.tsdate) as month,
round(sum(y.grossamount),2) as "labour cost",
sum(y.reg)+sum(y.ot) as "labour hours"
from
(
select OVERALL_ID,
BOAT_NAME
from TV_VESSEL_VISIT
group by OVERALL_ID,VESSEL_NAME
order by OVERALL_ID, VESSEL_NAME
) as x
inner join
(
select *
from TRANS
where ratedesc = 'Labour'
and opsdesc = 'Ops'
and ACTDESC = 'Nature of Job'
and terminal = 'UKN'
and reconciled = 'Y'
and TSDATE between '20-JAN-01' and '20-JAN-31'
) as y on x.BOAT_NAME = y.BOATNAME
group by OVERALL_ID, extract(year from tsdate), extract(month from tsdate)
order by OVERALL_ID, extract(year from tsdate), extract(month from tsdate);
Desired result is OVERALL_ID's labour cost/hours grouped into year and month
Currently getting the below error
ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
*Cause:
*Action:
Error at Line: 14 Column: 3
Trying to follow this link https://www.geeksengine.com/database/subquery/subquery-in-join-operation.php
Orable allows AS when declaring a column alias, but does not allow it for a table alias. The subquery alias is the same case as table alias. try ) x instead of ) as x, and the same thing for y. This is one of the syntax errors that causes ORA-00933.
If using subqueries DO NOT use ORDER BY inside those subqueries. There is no good purpose to the ordering, it just isn't required.
Try this:
SELECT
x.OVERALL_ID
, extract(year FROM y.tsdate) AS year
, extract(month FROM y.tsdate) AS month
, round(sum(y.grossamount), 2) AS "labour cost"
, sum(y.reg) + sum(y.ot) AS "labour hours"
FROM (
SELECT DISTINCT
OVERALL_ID
, BOAT_NAME
FROM TV_VESSEL_VISIT
) x
INNER JOIN (
SELECT *
FROM TRANS
WHERE ratedesc = 'Labour'
AND opsdesc = 'Ops'
AND ACTDESC = 'Nature of Job'
AND terminal = 'UKN'
AND reconciled = 'Y'
AND TSDATE >= to_date('2020-01-01','yyy-mm-dd') AND TSDATE < to_date('2020-02-01','yyyy-mm-dd')
) y ON x.BOAT_NAME = y.BOATNAME
GROUP BY
OVERALL_ID
, extract(year FROM tsdate)
, extract(month FROM tsdate)
ORDER BY
OVERALL_ID
, extract(year FROM tsdate)
, extract(month FROM tsdate)
;
Notes: I have removed the unwanted ORDER BY in the upper subquery, and changed this to use SELECT DISTINCT (it will produce the same result as the previous group by subquery). Also I have changed the syntax used for the date range. Please avoid using 2 digit year references, always use the full year. Additionally I always recommend avoiding the use of between for date ranges it is far more predictable to use the combination of >= with < as you see above. Plus I have used to_date() so it is clear what dates I am using for the date range - which will give you every row of data relevant to January 2020.
The previous between syntax could possibly miss a whole day's data

Is there any way for finding the Overlapping Time in table Workorder using DB2 SQL?

I want to make a report using DB2 SQL that will show the list of duration (hours) between 15th and 17th May. The current list look like this:
click here to view the list
As you can see, from WO-391296 (second row) it has overlapping time in ACTSTART and ACTFINISH.
I've already tried the Overlaps function. This is my query :
SELECT
*
FROM
workorder a,
workorder b
WHERE
a.wonum <> b.WONUM
AND (a.ACTSTART, a.ACTFINISH) OVERLAPS (b.ACTSTART, b.ACTFINISH)
AND DATE(a.ACTSTART) = '2019-05-15'
AND DATE(a.ACTFINISH) = '2019-05-17'
AND a.assetnum = 'A0000004'
AND DATE(b.ACTSTART) = '2019-05-15'
AND DATE(b.ACTFINISH) = '2019-05-17'
AND b.assetnum = 'A0000004' ;
But it doesn't work and just giving me the error message.:
SQL Error [42601]: An unexpected token "OVERLAPS" was found following "TSTART, a.ACTFINISH)". Expected tokens may include: "IN".. SQLCODE=-104, SQLSTATE=42601, DRIVER=3.64.114
Here's my actual full query :
SELECT assetnum, wonum, worktype, actstart, actfinish,
(DAY(ACTFINISH-ACTSTART)*24 + HOUR(ACTFINISH-ACTSTART)) + FLOAT(MINUTE(ACTFINISH-ACTSTART))/60 AS wotime
FROM (
SELECT assetnum, wonum, WORKTYPE, ACTSTART,
(CASE WHEN ACTFINISH IS NULL THEN '2019-05-17-24.00.00' ELSE ACTFINISH END) AS ACTFINISH
FROM workorder ast
WHERE istask=0 AND siteid = 'SBY' AND WORKTYPE = 'CM' AND
(ast.assetnum = 'A0000004' or
assetnum in (select distinct assetnum from asset ast where ast.parent = 'A0000004') or
assetnum in (select distinct assetnum from asset ast where ast.parent
in (select distinct assetnum from asset ast where ast.parent = 'A0000004'))) AND
(
(status IN ('COMP', 'CONFIRM', 'CLOSE') AND
(date(ACTFINISH) BETWEEN '2019-05-15' and '2019-05-17')) OR
(status IN ('INPRG', 'COMP', 'CONFIRM', 'CLOSE') AND
(date(ACTSTART) <= '2019-05-17' AND (date(ACTFINISH) > '2019-05-17' OR ACTFINISH IS null)))
)
);
The actual total duration of this list is 6 hours which is wrong, because I don't want to SUM the overlapping time.
So, the final result must be 3.5 hours (without WO-391296).
2 Intervals overlap if:
start of the 1-st is <= of end of the 2-nd
and
start of the 2-nd is <= of end of the 1-st
create or replace function overlaps_dates (a_from date, a_to date, b_from date, b_to date)
returns int
deterministic
no external action
contains sql
return case when min(a_from, a_to) <= max(b_from, b_to) and min(b_from, b_to) <= max(a_from, a_to) then 1 else 0 end;

no column was specified for column [x] of [table] and invalid column name

When running the following query, I get the desired results, but SSMS indicates that "no column was specified for column 2 of 'MonthlyTotals' when I mouse over the table alias and when I mouse over the "Totals" in the AVG function, it specifies that it's an invalid column name.
SELECT AVG(Totals) as 'MonthlyAvg' from
(
SELECT [DATE], SUM(Assets) as 'Totals'
FROM Assets inner join Funds on Assets.FundCode = Funds.FundCode
WHERE FeeGroupID = 17
and (([Date] >= '1/1/2013')
AND ([Date] <= '4/1/2013'))
and ((Funds.EndDt >= '4/1/2013') OR (Funds.EndDt is null))
GROUP BY [DATE]
) as MonthlyTotals
Total guess, but try this alternate syntax.
SELECT [MonthlyAvg] = AVG(Totals) from
(
SELECT [DateOf] = [DATE] , [Totals] = SUM(Assets)
FROM Assets inner join Funds on Assets.FundCode = Funds.FundCode
WHERE FeeGroupID = 17
and (([Date] >= '1/1/2013')
AND ([Date] <= '4/1/2013'))
and ((Funds.EndDt >= '4/1/2013') OR (Funds.EndDt is null))
GROUP BY [DATE]
) as MonthlyTotals