H2 database : Error when using window function inside CTE - sql

Using H2 database (version 1.4.200) I've encountered really strange error with usage of window functions inside CTE. When I include window function field into CTE and OVER() clause is empty it works correctly, but when I try to add ORDER BY/PARTITION BY inside the OVER() clause I'm encountering following error : '[42000][42000] Syntax error in SQL statement "WITH statement supports only SELECT, TABLE, VALUES, CREATE TABLE, INSERT, UPDATE, MERGE or DELETE statements" '
Non-working code sample:
WITH cte AS(
SELECT ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn
FROM TEST.HOLDING
)
SELECT *
FROM cte
One clarification: when I'm running statements using windows functions with PARTITION BY\ORDER BY parts not inside CTE it works well.
Working code sample:
SELECT ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn
FROM TEST.HOLDING
Test case for the issue:
CREATE TABLE PUBLIC.HOLDING(
CUST_NAME VARCHAR(50),
ORDER_DATE DATE
);
INSERT INTO PUBLIC.HOLDING(CUST_NAME, ORDER_DATE)
VALUES('Customer1',TO_DATE('20200201','YYYYMMDD')),
('Customer1',TO_DATE('20200202','YYYYMMDD')),
('Customer2',TO_DATE('20200201','YYYYMMDD')),
('Customer2',TO_DATE('20200202','YYYYMMDD'));
WITH cte AS(
SELECT CUST_NAME,
ORDER_DATE,
ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn
FROM PUBLIC.HOLDING
)
SELECT *
FROM cte;
SELECT CUST_NAME,
ORDER_DATE,
ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn
FROM PUBLIC.HOLDING;

you should tell us which database you uesd.if you use sql server,please check you code ,i gusse in front of 'with',whether not have ';'.
;WITH cte AS(
SELECT ROW_NUMBER() OVER (PARTITION BY CUST_NAME ORDER BY ORDER_DATE) AS rn
FROM TEST.HOLDING
)
SELECT *
FROM cte;

Related

oracle db from keyword not found where expected in double cte

I have a double cte expression , the first one join two tables and the second is implementing a partition by function:
with cte as (
select *
from memuat.product p
join memuat.licence l on p.id = l.product_id
where l.managed = 'TRUE'
),
joined as (
select
*,
row_number() over (partition by id order by id) as rn
from cte
)
select * from joined;
I get the following error:
ORA-00923: FROM keyword not found where expected, ERROR at line 12.
I cannot figure out which syntax error is wrong in my query.
Oracle is nitpicking when it comes to SELECT *. SELECT * means "select everything", so how can you possibly add something to it? In Oracle you cannot SELECT *, 1 AS something_else FROM some_table. You must have SELECT some_table.*, 1 AS something_else FROM some_table, so you are no longer selecting "everything", but "everything from the table" :-)
You have
select
*,
row_number() over (partition by id order by id) as rn
from cte
It must be
select
cte.*,
row_number() over (partition by id order by id) as rn
from cte
instead.

SQL Server : using CTE row partition to serialize sequential timestamps

I think I just need a little help with this but is there a way to incrementally count steps in SQL using some type of CTE row partition? I'm using SQL Server 2008 so won't be able to use the LAG function.
In the below, I am trying to find a way to calculate the Step Number as pictured below where for each unique ITEM in my table, in this case G43251, it calculates the process Step_Number based on the Date (timestamp) and the process type. For those with the same timestamp & process_type, it would label them both as the same Step_Number as there other fields that could cause the timestamp to repeat twice.
Right now I am playing around with this below and seeing how maybe I could fit in a DISTINCT timestamp methodology ? So that it doesn't count each row as something new.
WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY Timestamp_Posted DESC)
- ROW_NUMBER() OVER (PARTITION BY Item ORDER BY Timestamp_Posted Desc) rn
FROM
#t1
)
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Item, rn ORDER BY Timestamp_Posted DESC) rn2
FROM
cte
ORDER BY
Timestamp_Posted DESC
Please use dense_rank() instead of row_number()
SELECT *, dense_rank() OVER(Partition By Item ORDER BY Timestamp_Posted, Process_Type ) Step_Number
FROM #t1
ORDER BY Timestamp_Posted DESC

Filter out null values resulting from window function lag() in SQL query

Example query:
SELECT *,
lag(sum(sales), 1) OVER(PARTITION BY department
ORDER BY date ASC) AS end_date_sales
FROM revenue
GROUP BY department, date;
I want to show only the rows where end_date is not NULL.
Is there a clause used specifically for these cases? WHERE or HAVING does not allow aggregate or window function cases.
One method uses a subquery:
SELECT r.*
FROM (SELECT r. *,
LAG(sum(sales), 1) OVER (ORDER BY date ASC) AS end_date
FROM revenue r
) r
WHERE end_date IS NOT NULL;
That said, I don't think the query is correct as you have written it. I would assume that you want something like this:
SELECT r.*
FROM (SELECT r. *,
LEAD(end_date, 1) OVER (PARTITION BY ? ORDER BY date ASC) AS end_date
FROM revenue r
) r
WHERE end_date IS NOT NULL;
Where ? is a column such as the customer id.
Try this
select * from (select distinct *,SUM(sales) OVER (PARTITION BY dept) from test)t
where t.date in(select max(date) from test group by dept)
order by date,dept;
And one more simpler way without sub query
SELECT distinct dept,MAX(date) OVER (PARTITION BY dept),
SUM(sales) OVER (PARTITION BY dept)
FROM test;

Get the last time a value has changed in Google BigQuery

I have an employee database which contains records about employees. The fields are :
employee_identifier
employee_salary
date_of_the_record
I would like to get, for each record, the date of the last change in employee_salary. Which SQL query could work ?
I have tried with multiple sub-queries, but it does not work.
Below is for BigQuery Standard SQL
#standardSQL
SELECT * EXCEPT(arr),
(SELECT MAX(date_of_the_record) FROM UNNEST(arr)
WHERE employee_salary != t.employee_salary
) AS last_change_in_employee_salary
FROM (
SELECT *, ARRAY_AGG(STRUCT(employee_salary, date_of_the_record)) OVER(win) arr
FROM `project.dataset.employee_database`
WINDOW win AS (PARTITION BY employee_identifier ORDER BY date_of_the_record)
) t
use row_number()
with cte as
(
select *,
row_number()over(partition by employee_identifier order by date_of_the_record desc) rn from table_name
) select * from cte where rn=1
You can also do this without a subquery. If you want all the columns:
SELECT as value ARRAY_AGG(t ORDER BY date_of_the_record DESC LIMIT 1)[ordinal(1)]
FROM t t
GROUP BY employee_identifier;
If you just want the date, use GROUP BY:
SELECT employee_identifier, MAX(date_of_the_record)
FROM t t
GROUP BY employee_identifier;

How to convert this query to SQL Server 2000 syntax

I am running this query to SQL Server 2008+ but it doesn't work on SQL Server 2000.
and i need this to execute.
WITH CTE AS (
SELECT
custnum,
custname,
RN = ROW_NUMBER() OVER( PARTITION BY custnum, custname ORDER BY custnum )
FROM
cust
)
SELECT
*
FROM
CTE
WHERE RN > 1
thank you so much for your help!
Prior to SQL Server 2005, this problem domain was solved with ordered inserts into a #temp table with an IDENTITY column to generate the sequence number. This would solve RANK() and ROW_NUMBER() requirements.
E.g.:
-- Create empty temp table
SELECT custnum, custname, IDENTITY(INT, 1, 1) as RN
INTO #cust
FROM cust
WHERE 0 = 1
-- Populate with ORDER BY, to generate ascending RN
INSERT INTO #cust
(custnum, custname)
SELECT
custnum, custname
FROM
cust
ORDER BY
custnum, custname
At that point, you can query MIN() for each custnum/custname grouping and use that as you'd use the CTE.
However ... is ROW_NUMBER() really what you want here ? Seems like you'd want RANK(), not ROW_NUMBER().
See if this works
select custnum,custname from
(
select (select count(*) from cust as t1 where t1.custnum<=t2.custnum) as sno,
custnum,custname from cust as t2
) as t
where sno>1