Getting ORA-00928: missing SELECT keyword error - sql

I am getting an error
ORA-00928: missing SELECT keyword
while running this query:
WITH Dups AS
(
SELECT
ID, AMOUNT, BATCH_ID, PROCESS_DATE, ITEM_NUMBER, ERROR_TYPE, INSERTED_DATE,
ROW_NUMBER() OVER(PARTITION BY ID, ERROR_TYPE ORDER BY ID) AS rn
FROM
ERROR_TABLE
WHERE
inserted_date >= TRIM(TO_DATE('01-AUG-17', 'DD-MON-YY'))
AND inserted_date <= TRIM(TO_DATE('11-AUG-17', 'DD-MON-YY'))
)
DELETE FROM Dups
WHERE rn > 1

This is not how to delete duplicates in Oracle. Inspired, but not for that database. Something like this:
delete error_table et
where et.inserted_date >= date '2017-08-01' and
et.inserted_date <= date '2017-08-11' and
rowid > (select min(et2.rowid)
from error_table et2
where et2.inserted_date >= date '2017-08-01' and
et2.inserted_date <= date '2017-08-11' and
et2.id = et.id and
et2.error_type = et.error_type
);

Related

I need to write a query to mark previous record as “Not eligible ” if a new record comes in within 30 days with same POS Order ID

I have a requirement to write a query to retrieve the records which have POS_ORDER_ID in the table with same POS_ORDER_ID which comes within 30days as new record with status 'Canceled', 'Discontinued' and need to mark previous POS_ORDER_ID record as it as not eligible
Table columns:
POS_ORDER_ID,
Status,
Order_date,
Error_description
A query containing MAX() and ROW_NUMBER() analytic functions might help you such as :
with t as
(
select t.*,
row_number() over (partition by pos_order_id order by Order_date desc ) as rn,
max(Order_date) over (partition by pos_order_id) as mx
from tab t -- your original table
)
select pos_order_id, Status, Order_date, Error_description,
case when rn >1
and t.status in ('Canceled','Discontinued')
and mx - t.Order_date <= 30
then
'Not eligible'
end as "Extra Status"
from t
Demo
Please use below query,
Select and validate
select POS_ORDER_ID, Status, Order_date, Error_description, row_number()
over(partition by POS_ORDER_ID order by Order_date desc)
from table_name;
Update query
merge into table_name t1
using
(select row_id, POS_ORDER_ID, Status, Order_date, Error_description,
row_number() over(partition by POS_ORDER_ID order by Order_date desc) as rnk
from table_name) t2
on (t1.POS_ORDER_ID = t2.POS_ORDER_ID and t1.row_id = t2.row_id)
when matched then
update
set
case when t2.rnk = 1 then 'Canceled' else 'Not Eligible';

SQL - How to perform a nested SELECT with multiple queries from the same table?

I wrote a nested select query and it's working correctly.
select user_id, transaction_id, t_timestamp
from (
select *, row_number() over (partition by (user_id || '*' || transaction_id) order by f_time asc) rownum
from transactionMetricsView
where metric_1 in (select metric_value
from main.metrics
where metric_key = 'metric_type_1')
)
where rownum = 1
But also the main.metrics table has an m_date field so I need to check if the date is within a given range.
But I'm not sure how to implement it correctly.
I think it should look something like the below query, but it's more like a pseudo-code now.
select user_id, transaction_id, t_timestamp
from (
select *, row_number() over (partition by (user_id || '*' || transaction_id) order by f_time asc) rownum
from transactionMetricsView
where metric_1 in (select metric_value
from main.metrics
where metric_key = 'metric_type_1')
and (select m_date
from main.metrics between $startDate and $endDate)
)
where rownum = 1
This might work:
select user_id, transaction_id, t_timestamp from (select *, row_number() over (partition by (user_id || '*' || transaction_id) order by f_time asc) rownum
from transactionMetricsView
where metric_1 in (select metric_value
from main.metrics
where metric_key = 'metric_type_1'
and m_date between $startDate and $endDate
)
and rownum = 1

Invalid column reference in hive

When I run the below query, I get the error "Invalid column reference: cnt". Any suggestions would be great !!
select count(customer) as cnt from (
select customer, concat(visid, lowid), count(name)
from tab1 where date_time between '2017-05-01 00:00:00' and '2017-05-31 23:59:59' and name in ('payment: Complete', 'check: Complete')
group by evar71, concat(visid, lowid)) t1
where cnt > 1;
Another way to do it.
select count(customer) as cnt from (
select customer, concat(visid, lowid), count(name)
from tab1 where date_time between '2017-05-01 00:00:00' and '2017-05-31 23:59:59' and name in ('payment: Complete', 'check: Complete')
group by evar71, concat(visid, lowid)) t1
having count(customer) > 1;
WHERE filter applied before aggregation
that is why where cnt > 1 does not work. There is HAVING keyword which introduces a condition on aggregations, it works as filter after aggregation.
select count(customer) cnt
...
where rows_filter_condition_here --before aggregation
having count(customer) > 1 --aggregation results filter
order by cnt desc --this works after aggregation
I think hive prefers aliases in the group by. In addition, several column aliases are not correct:
select count(customer) as cnt
from (select customer, concat(visid, lowid) as ids, count(name) as cc
from tab1
where date_time >= '2017-05-01' and date_time < '2017-06-01' and
name in ('payment: Complete', 'check: Complete')
group by customer, ids
) t1
where cc > 1;

SQL Server 2008 - Finding duplicates using ROW_NUMBER

i have the following SQL which works to find duplicates
SELECT *
FROM (SELECT
id,
ShipAddress,
ShipZIPPostal,
ROW_NUMBER() OVER (PARTITION BY shipaddress, shipzippostal ORDER BY shipaddress) ROWNUM
FROM orders
WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())) x
WHERE rownum > 1
I would like to only see rows where, if the value of Rownum > 1 then i would like to see its corresponding row where rownum =1.
So basically, if a row has duplicates, i want to see the original row and all its duplicates.
If a row does not have duplicates, then i don't want to see it (it will have rownum = 1 )
How would i do this please?
cheers
Use count(*) rather than row_number():
SELECT *
FROM (SELECT id, ShipAddress, ShipZIPPostal,
COUNT(*) OVER (PARTITION BY shipaddress, shipzippostal) as cnt
FROM orders
WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())
) x
WHERE cnt > 1;
In addition to Gordon's answer, if you want to keep the row_number() approach for some academic reason, you can do this:
SELECT *
FROM (SELECT
id,
ShipAddress,
ShipZIPPostal,
ROW_NUMBER() OVER (PARTITION BY shipaddress, shipzippostal ORDER BY shipaddress) ROWNUM
FROM orders
WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())) x
WHERE EXISTS(
SELECT * FROM x x2
WHERE x.shipaddress=x2.shipaddress
AND x.shipzippostal=x2.shipzippostal
AND x2.ROWNUM>1
)
I'd actually prefer a cte structure like this personally:
WITH cte AS (
SELECT
id,
ShipAddress,
ShipZIPPostal,
ROW_NUMBER() OVER (PARTITION BY shipaddress, shipzippostal ORDER BY shipaddress) ROWNUM
FROM orders
WHERE CONVERT(date, orderdate) = CONVERT(date, GETDATE())
)
SELECT *
FROM cte
WHERE EXISTS(
SELECT * FROM cte x2
WHERE cte.shipaddress=x2.shipaddress
AND cte.shipzippostal=x2.shipzippostal
AND x2.ROWNUM>1
)
You could add a second row_number, but change the order by to ID so it will be different, and compare the 2 row_numbers
SELECT
*
FROM
(SELECT
id,
ShipAddress,
ShipZIPPostal,
ROW_NUMBER() OVER (PARTITION BY shipaddress,shipzippostal ORDER BY id) ROWNUM1,
ROW_NUMBER() OVER (PARTITION BY shipaddress,shipzippostal ORDER BY id DESC) ROWNUM2
FROM
orders
WHERE
CONVERT(DATE,orderdate) = CONVERT(DATE,GETDATE())
) x
WHERE
ROWNUM1 <> ROWNUM2

How to select specific rows in PostgreSQL query?

I have written a query to get the 'reason_code' and 'app_count' for top five rows from result set and sum of remaining app_count under name 'others'.
Here what I have tried:
(SELECT a.app_pgm_rsnd_rsn_cd, a.denied_app_count
FROM (SELECT app_pgm_rsnd_rsn_cd ,COUNT(1) as denied_app_count
FROM app_pgm_choice, ead_case
where app_pgm_sts= 'DN'
AND app_pgm_req_dt >= '20150101'
AND app_pgm_req_dt <= '20150130'
AND EAD_CS_APP_NUM = APP_PGM_NUM
AND EAD_CS_SEND_CNTY_ID = '19'
AND EAD_CS_TRAN_STS = 'PE'
GROUP BY app_pgm_rsnd_rsn_cd
ORDER BY denied_app_count desc) a
WHERE ROWNUM <=5 )
UNION ALL
(SELECT 'OTHERS' as app_pgm_rsnd_rsn_cd, SUM(b.denied_app_count) as denied_app_count
FROM (SELECT app_pgm_rsnd_rsn_cd ,COUNT(1) as denied_app_count
FROM app_pgm_choice, ead_case
where app_pgm_sts= 'DN'
AND app_pgm_req_dt >= '20150101'
AND app_pgm_req_dt <= '20150130'
AND EAD_CS_APP_NUM = APP_PGM_NUM
AND EAD_CS_SEND_CNTY_ID = '19'
AND EAD_CS_TRAN_STS = 'PE'
GROUP BY app_pgm_rsnd_rsn_cd
ORDER BY denied_app_count desc) b
WHERE ROWNUM >=5 )
But when I run this query it shows following error message:
ERROR: column "rownum" does not exist
LINE 13: WHERE ROWNUM <=5 )
^
********** Error **********
ERROR: column "rownum" does not exist
SQL state: 42703
Character: 397
What is option for ROWNUM variable?
I think you are looking for the LIMIT clause.
SELECT *
FROM sometable
ORDER BY denied_app_count DESC
LIMIT 5
ROWNUM is an Oracle-ism.
For greater-than, you can use OFFSET:
SELECT *
FROM sometable
ORDER BY denied_app_count DESC
OFFSET 5
to skip the first 5 rows and return the rest.
The two can be, and often are, combined when doing things like pagination.
See LIMIT and OFFSET
In PostgreSQL you can use the row_number() window function, but for your purpose here it's unnecessary. On the other hand, it might be faster to do a single query with row_number then query the result table twice to get the two parts. Try that approach and see if it performs better.
Try this query
(SELECT a.app_pgm_rsnd_rsn_cd, a.denied_app_count
FROM (SELECT app_pgm_rsnd_rsn_cd ,COUNT(1) as denied_app_count
,row_number() OVER (ORDER BY app_pgm_rsnd_rsn_cd ) AS ROWNUM
FROM app_pgm_choice, ead_case
where app_pgm_sts= 'DN'
AND app_pgm_req_dt >= '20150101'
AND app_pgm_req_dt <= '20150130'
AND EAD_CS_APP_NUM = APP_PGM_NUM
AND EAD_CS_SEND_CNTY_ID = '19'
AND EAD_CS_TRAN_STS = 'PE'
GROUP BY app_pgm_rsnd_rsn_cd
ORDER BY denied_app_count desc) a
WHERE ROWNUM <=5 )
UNION ALL
(SELECT 'OTHERS' as app_pgm_rsnd_rsn_cd, SUM(b.denied_app_count) as denied_app_count
FROM (SELECT app_pgm_rsnd_rsn_cd ,COUNT(1) as denied_app_count
,row_number() OVER (ORDER BY app_pgm_rsnd_rsn_cd ) AS ROWNUM
FROM app_pgm_choice, ead_case
where app_pgm_sts= 'DN'
AND app_pgm_req_dt >= '20150101'
AND app_pgm_req_dt <= '20150130'
AND EAD_CS_APP_NUM = APP_PGM_NUM
AND EAD_CS_SEND_CNTY_ID = '19'
AND EAD_CS_TRAN_STS = 'PE'
GROUP BY app_pgm_rsnd_rsn_cd
ORDER BY denied_app_count desc) b
WHERE ROWNUM >=5 )