Postgresql - Syntax error - while using with table_name as - postgresql

Not sure what needs to be done , i am using pgadmin3 but regardless of the GUI i keep getting the same error .
Below is my query :
with base_table as
(select row_number() over (partition by p.customer_id order by p.payment_date ) as early_order,
row_number() over (partition by p.customer_id order by p.payment_date desc) as last_order
from payment p)
Syntax error at the end of input
I have even tried adding a semicolon at the end, doesnt work :
with base_table as
(select row_number() over (partition by p.customer_id order by p.payment_date ) as early_order,
row_number() over (partition by p.customer_id order by p.payment_date desc) as last_order
from payment p);
Syntax error near ";"
The inner query (which is below) works just fine :
select row_number() over (partition by p.customer_id order by p.payment_date ) as early_order,
row_number() over (partition by p.customer_id order by p.payment_date desc) as last_order
from payment p
Its only when i use with table_name as , that the errors start to show up.

You need to add main select:
with base_table as (
select row_number() over(partition by p.customer_id order by p.payment_date) as early_order,
row_number() over(partition by p.customer_id order by p.payment_date desc) as last_order
from payment p)
SELECT *
FROM base_table

Related

row number partition mysql workbench

what is wrong with this
select
ID
,SYSCODE
,LID
,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY SYSCODE, LID) AS row_num
from prod_sys.P_ENTERPRISE
it works in management studio but not in mysql workbench
ROW_NUMBER() is not there in MYSQL, rewrite the query like below.
select
ID
,SYSCODE
,LID
,#row_num := #row_num + 1 as Row_number
from prod_sys.P_ENTERPRISE join (SELECT #row_num := 0) a;

Creating a Void Function in PostgreSQL

I am getting an error on this create function code in Postgresql. The error says it is happening around Line 2 at DELETE, but it happens at WITH if I remove that line so I think it is a problem with the format of my Creat Function
create or replace function retention_data(shopId integer) returns void as $$
delete from retention where shop_id = shopId;
WITH ret_grid_step1 as (
select * from (
SELECT
order_id as order_name,
cust_name as cust_name,
email as email,
date(order_date) as created_at,
count(*) as num_items_in_order,
sum(total_price) as sales ,
rank() over (partition BY order_id ORDER BY cust_name ASC) as rnk_shipping_name,
rank() over (partition BY order_id ORDER BY email ASC) as rnk_email
FROM orders
WHERE shop_id = shopId
and order_date is not null and order_date > now()::date - 365 and order_date < now()::date + 1
group by 1,2,3,4
) x
where rnk_shipping_name = 1 and rnk_email = 1
)
insert into retention(shop_id, cust_name, email, last_purchase_dt, total_sales, num_orders, days_since_last_order)
select
shopId as shop_id,
coalesce(b.cust_name,'null') as cust_name,
a.email,
a.last_purchase_dt,
total_sales,
num_orders,
current_date - last_purchase_dt as days_since_last_order
from (
select
email,
max(created_at) as last_purchase_dt,
count(*) as num_orders,
sum(sales) as total_sales
from ret_grid_step1
group by 1
) as a
left join (
select
email,
cust_name,
rank() over (partition BY email ORDER BY created_at DESC) as rnk
from ret_grid_step1
--where cust_name is not null
group by 1,2,created_at
) as b
on a.email = b.email
where b.rnk = 1
and a.email <> '';
$$ language plpgsql;

How to use a Table type in query

I have 9000 row in News table and use this code for selecting 20 from it:
Select *
From (
Select *, ROW_NUMBER() OVER (ORDER BY DateSend DESC) AS Num
From News
Where SubjectID in(Select MenuSubject.SubjectID
From MenuSubject inner join Menu on MenuSubject.MenuID = Menu.MenuID)
) as myTable
where myTable.Num BETWEEN 100 and 120
But time is 28 second spent reading! Also, I test this query with out join table and get result at 1 second.
So, I want use Table type for select join table and use this in query. I made new Table type using the following code:
DECLARE #MyTable2 IntListTable
Insert Into #MyTable2
Select MenuSubject.SubjectID
From MenuSubject inner join Menu on MenuSubject.MenuID = Menu.MenuID
Select *
From (
Select *, ROW_NUMBER() OVER (ORDER BY DateSend DESC) AS Num
From News
Where SubjectID in #MyTable2
) as myTable
where myTable.Num BETWEEN 100 and 120
But get Error in
SubjectID in #MyTable2
Error:
Incorrect syntax near '#MyTable2'.
Edit:
I test my code with:
Select myTable.Title
or use this code instead join table:
Where SubjectID in(13,14,20,21,25,24,26,24,28,29,30,54,55,60,47,98,99,65,14,20,33,666,987,254)
get result at 1 second.
but use this code in query:
Select myTable.MoreText
time is 28 second spent reading!. why!?
Try this,
Select x.Num
From (
Select *, ROW_NUMBER() OVER (ORDER BY DateSend DESC) AS Num
From News
Where SubjectID in(Select MenuSubject.SubjectID
From MenuSubject inner join Menu on MenuSubject.MenuID = Menu.MenuID)
) x
where x.Num <21
WITH myTempTable as (Select MenuSubject.SubjectID
From MenuSubject inner join Menu on MenuSubject.MenuID = Menu.MenuID)
Select *
From (
Select *, ROW_NUMBER() OVER (ORDER BY DateSend DESC) AS Num
From News
Where SubjectID in (SELECT SubjectID FROM myTempTable)
) as myTable
where myTable.Num BETWEEN 100 and 120
You can try above query.
There is absolutely no need for a User-Defined Table Type in this query. It adds work but no actual benefit.
The problem is most likely the fact that you are using an IN list as those translate out to be an OR condition for each of the values. But an IN list isn't needed either.
This query can actually be simplified by rethinking it in terms of an INNER JOIN, which should be better as it will allow the Query Optimizer to do its job.
SELECT *
FROM (
SELECT nw.*, ROW_NUMBER() OVER (ORDER BY DateSend DESC) AS [Num]
FROM News nw
INNER JOIN (
MenuSubject
INNER JOIN Menu
ON MenuSubject.MenuID = Menu.MenuID
) ON MenuSubject.SubjectID = nw.SubjectID
) AS myTable
WHERE myTable.Num BETWEEN 100 AND 120;
One final simplification that can be made, though I doubt it is needed here since 9000 rows is almost no data at all, is to first dump the results to a local temporary table and then use that in the INNER JOIN:
CREATE TABLE #Subjects
(
SubjectID INT NOT NULL -- PRIMARY KEY -- test with and without PK to see if it helps
);
INSERT INTO #Subjects (SubjectID)
SELECT MenuSubject.SubjectID
FROM MenuSubject
INNER JOIN Menu
ON Menu.MenuID = MenuSubject.MenuID;
SELECT *
FROM (
SELECT nw.*, ROW_NUMBER() OVER (ORDER BY DateSend DESC) AS [Num]
FROM News nw
INNER JOIN #Subjects sub
ON sub.SubjectID = nw.SubjectID
) AS myTable
WHERE myTable.Num BETWEEN 100 AND 120;

ROW_NUMBER() in Redshift to select biggest row from each group?

I need to select one row from each group based on COUNT(1) field.
In other databases I'd use ROW_NUMBER() function, which in redshift is unsupported yet.
The answer is to use a SUM(1) OVER(PARTITION BY group_field ORDER BY order field ROWS UNBOUNDED PRECEDING) construct like that:
SELECT id,
name,
cnt
FROM
(SELECT id,
name,
count(*) cnt,
sum(1) over (partition BY id ORDER BY cnt DESC ROWS UNBOUNDED PRECEDING) AS row_number
FROM table
GROUP BY id,
name)
WHERE row_number = 1
ORDER BY name

Order by on an inline view

I would like to get the top 10 data from a table which needs to be sorted in ascending order in a outer query. Below is the pseudocode of the query. What are the options other than using table valued functions?
select * from
(select top 10 tour_date
from tourtable
order by tour_date desc)
order by tour_date asc
Your query as written should work, you'd just need to alias the subquery:
select *
from (select top 10 tour_date from tourtable order by tour_date desc) t
order by tour_date asc
Another alternative, assuming SQL Server 2005+:
SELECT t.tour_date
FROM (SELECT tour_date, ROW_NUMBER() OVER(ORDER BY tour_date DESC) AS RowNum
FROM tourtable) t
WHERE t.RowNum <= 10
ORDER BY t.tour_date ASC
which could also be written with a CTE:
WITH cteRowNum AS (
SELECT tour_date, ROW_NUMBER() OVER(ORDER BY tour_date DESC) AS RowNum
FROM tourtable
)
SELECT tour_date
FROM cteRowNum
WHERE RowNum <= 10
ORDER BY tour_date ASC
Tested in a non-tsql context:
select * from (select tour_date from tourable order by tour_date desc limit 10) a order by tour_date asc