Hide row_number() column - sql

I'm using row_number() as a counter to see if there is any data with the conditions i specified. I want rows where p = 1 but I don't need the actual column that gives p=1 for every row. Is there any way I can exclude that column?
with base as(
select
state.simple as State,
customer_status,
cast(created_at as date) as Order_Date,
cast(dbt_valid_from as date) as Aktiv_Start_Date,
**row_number() over (partition by lower(email) order by dbt_valid_from) as p**
from analytics.fct_orders_all
left join `analytics.dim_customers_history` on
lower(customer.email) = lower(email)
where customer_status like "Aktiv%"
and state.simple = "pending"
and dbt_valid_from between created_at and timestamp_add(created_at, interval 14 day)
)
select *
from base
**where p = 1**
order by 4 desc

Big Query has a nice extension called SELECT * EXCEPT:
with base as (...)
select * except(p) from base where p = 1 order by 4

BigQuery allows this using except:
select b.* except (p)
from base b
where p = 1;
You can also use replace to change the names of columns as well. These very handy modifiers are explained in the documentation.

you can always avoid using select *
I have a similar query here:
;with base as(
select
'Pending' as State,
a.preferredName,
cast(createDate as date) as Order_Date,
cast(birthdate as date) as Aktiv_Start_Date,
a.nationalitycode,
row_number() over (partition by a.nationalitycode order by a.nationalitycode) as p
from [app].[applicant] a
)
select *
from base
where p = 1
order by 4 desc
Putting the list of columns that I want to see implicit in the select:
;with base as(
select
'Pending' as State,
a.preferredName,
cast(createDate as date) as Order_Date,
cast(birthdate as date) as Aktiv_Start_Date,
a.nationalitycode,
row_number() over (partition by a.nationalitycode order by a.nationalitycode) as p
from [app].[applicant] a
)
select
State,
preferredName,
Order_Date,
Aktiv_Start_Date,
nationalityCode
from base
where p = 1
order by 4 desc

Related

Selecting the latest order

I need to select the data of all my customers with the records displayed in the image. But I need to get the most recent record only, for example I need to get the order # E987 for John and E888 for Adam. As you can see from the example, when I do the select statement, I get all the order records.
You don't mention the specific database, so I'll answer with a generic solution.
You can do:
select *
from (
select t.*,
row_number() over(partition by name order by order_date desc) as rn
from t
) x
where rn = 1
You can use analytical function row_number.
Select * from
(Select t.*,
Row_number() over (partition by customer_id order by order_date desc) as rn
From your_table t) t
Where rn = 1
Or you can use not exists as follows:
Select *
From yoir_table t
Where not exists
(Select 1 from your_table tt
Where t.customer_id = tt.custome_id
And tt.order_date > t.order_date)
You can do it with a subquery that finds the last order date.
SELECT t.*
FROM yoir_table t
JOIN (SELECT tt.custome_id,
MAX(tt.order_date) MaxOrderDate
FROM yoir_table tt
GROUP BY tt.custome_id) AS tt
ON t.custome_id = tt.custome_id
AND t.order_date = tt.MaxOrderDate

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;

Select the Max date time for single User

I have a table like this,
Date User
15-06-2018 A
16-06-2018 A
15-06-2018 B
14-06-2018 C
16-06-2018 C
I want to get the output like this,
Date User
16-06-2018 A
15-06-2018 B
16-06-2018 C
I tried Select Max(date),User from Table group by User
Based on your comment, I assume you have duplicated results in those 80 columns when you group by them. Assuming so, here's one option using row_number to always return 1 row per user:
select *
from (
select *, row_number() over (partition by user order by date desc) rn
from yourtable
) t
where rn = 1
You can use correlation subquery :
select t.*
from table t
where date = (select max(t1.date)
from table t1
where t1.user = t.user
);
However, i would also recommend row_number() :
select top (1) with ties *
from table t
order by row_number() over (partition by user order by date desc);
You can also use a ranking function
SELECT User, Date
FROM
(
SELECT User, Date
, Row_id = Row_Number() OVER (Partition by User, ORDER BY User, Date desc)
FROM table
)q
WHERE Row_Id = 1
I would suggest you this
Select * from table t where exist
(Select 1 from
(Select user, max(date) as date from table) A
Where A.user = t.user and A.date = t.date )

Getting the last value of a column for an object with many entries

Please consider the below Repair_Table of a car-repair workshop.
I'm trying to get the last "Repair_Status" value for each car within a given day.
"Repair_Update" column will have a new entry for each change during the car repair process: like the repair status, the repair name or the repair team and repair sub-task which are stored in a different table..
I tried this query but it's not giving me what I need:
select distinct(Car_ID), Repair_Status
from Repair_Table r1
left join (select Car_ID, max(Repair_Update) from Repair_Table
group by Car_ID) r2
on r2.Repair_Update = r1.Repair_Update
where convert(date,Repair_Start) = '20180122'
Window functions are an easy way to do this:
select rt.*
from (select rt.*,
row_number() over (partition by car_id, cast(repair_update as date)
order by repair_update desc
) as seqnum
from Repair_Table rt
where convert(date, Repair_Start) = '20180122'
) rt
where seqnum = 1;
You can remove the where clause if you want this information on multiple dates -- or even on all dates.
Using row_number() function:
select Car_ID, Repair_Status
from (
select Car_ID, Repair_Status
row_number() over (partition by Car_ID order by Repair_Update desc) as rnk
from Repair_Table
) t
where t.rnk = 1

Filter the table with latest date having duplicate OrderId

I have following table:
I need to filter out the rows for which start date is latest corresponding to its order id .With reference to given table row no 2 and 3 should be the output.
As row 1 and row 2 has same order id and order date but start date is later than first row. And same goes with row number 3 and 4 hence I need to take out row no 3 . I am trying to write the query in SQL server. Any help is appreciated.Please let me know if you need more details.Apologies for poor English
You can do this easily with a ROW_NUMBER() windowed function:
;With Cte As
(
Select *,
Row_Number() Over (Partition By OrderId Order By StartDate Desc) RN
From YourTable
)
Select *
From Cte
Where RN = 1
But I question the StartDate datatype. It looks like these are being stored as VARCHAR. If that is the case, you need to CONVERT the value to a DATETIME:
;With Cte As
(
Select *,
Row_Number() Over (Partition By OrderId
Order By Convert(DateTime, StartDate) Desc) RN
From YourTable
)
Select *
From Cte
Where RN = 1
Another way using a derived table.
select
t.*
from
YourTable t
inner join
(select OrderId, max(StartDate) dt
from YourTable
group by OrderId) t2 on t2.dt = t.StartDate and t2.OrderId = t.OrderId