PostgresSQL select - sql

Im beginner in sql, so i need help...
I have tabe like this:
enter image description here
I need that my query bring back service_id: 5 and id:8, 2 rows(or its depends how many client_ids ill put in my where condition), with client_id, service_type_id, service_id, because service_start_date is max on those 2 clients. I have a full list of clients and i need to do it, thanks for the answers.

i used row_number() OVER( PARTITION BY client_id ORDER BY (service_start_date) desc)
it will give rownumber with client_id service_start_date descending
select
*
from (select
service_id,
service_name,
service_start_date,
service_end_date,
client_id,
service_type_id,
row_number() OVER( PARTITION BY client_id ORDER BY (service_start_date) desc) as ord
from servicetable
/* add where condition here*/
order by service_id) as drt
where ord=1

Related

SUM most recent ID/Product combinations for the latest date

select * from
(select Id, Prodcut, Billing_date
, row_number() over (partition by Id, product order by Billing_date desc) as RowNumber
,sum(Revenue)
from Table1
group by 1,2,3,4,1) a
where a.rowNumber = 1
There are rows where Id+product combination repeats for latest billing date and which causing some data to be missed out. I am trying to add sum with row_number to sum all the ID&product combinations for the latest date but not able to make it work.
Can anyone please help me out here!
Data Sample Image
Database: Athena, Dbeaver
I would expect this to do what you want:
select *
from (select Id, Product, Billing_date,
row_number() over (partition by Id, product order by Billing_date desc) as seqnum,
sum(Revenue)
from Table1
group by Id, Product, Billing_date
) t1
where seqnum = 1;
Your group by columns do not seem correct. I'm surprised your query runs in any datbase.

Rank() based on column entries while the data is ordered by date

I'm trying to use dense_rank() function over the pagename column after the data is ordered by time_id.
Expected output in rank column, rn, is: [1,2,2,3,4].
Currently I wrote it as:
with tbl2 as
(select UID, pagename, date_id, time_id, source--, dense_rank() over(partition by UID order by pagename) as rn
from tbl1
order by time_id)
select *, dense_rank() over(partition by UID order by time_id, pagename) as rn
from tbl2
Any help would be appreciated
Edit 1: What I am trying to achieve here is to give ranks, as per the user on-screen action flow, to the pages that are visited. Suppose if the same page 'A' is visited back after visiting a different page 'B' then the ranks for these page visits A, B, A will be 1,2,3 (note that the same page A has different ranks 1 & 3)
step-by-step demo:db<>fiddle
SELECT
*,
SUM(is_diff) OVER (ORDER BY date_id, time_id, page)
FROM (
SELECT
*,
CASE WHEN page = lag(page) over (order by date_id, time_id) THEN 0 ELSE 1 END as is_diff
FROM mytable
)s
This looks exactly like a problem I asked some years ago: Window functions: PARTITION BY one column after ORDER BY another
You want to execute a window function on columns (uuid, page) but want to keep the current order which is given by unrelated columns (date_id, time_id).
The problem is, that PARTITION BY orders the records before the ORDER BY clause. So, it defines the primary order and this is not expected.
Once I found a solution for that. I adapted it to your used case. Please read the explanation over there: https://stackoverflow.com/a/52439794/3984221
Interesting part: Your special rank() case is not explicitly required in the query, because my solution creates that out-of-the-box ("by accident" so-to-speak ;) ).
Hmmm . . . If you want the pages ordered by their earliest time, then use two levels of window functions:
select t.*,
dense_rank() over (partition by uid order by min_rn, pagename) as ranking
from (select t.*,
min(rn) over (partition by uid, pagename) as min_rn
from t
) t
Note: This uses rn as a convenient shortcut because the date/time is split into two columns. You can also combine them:
select t.*,
dense_rank() over (partition by uid order by min_dt, pagename) as ranking
from (select t.*,
min(date_id || time_id) over (partition by uid, pagename) as min_dt
from t
) t;
Note: This solution is different from S_man's. On your sample data, they do the same thing. However, if the user returns to a page, then his gives page a new ranking. This gives the page the same ranking as the first time it appears. It is not clear what you really want.
You can use DENSE_RANK() like this for your requirment,
SELECT
u_id,
page_name,
date_id,
time_id,
source,
DENSE_RANK()
OVER (
PARTITION BY page_name
ORDER BY u_id DESC
) rn
FROM ( SELECT * FROM tbl1 ORDER BY time_id ) AS result;

Including VersionNumber with record

I currently have a version number column in my table and all of them are set to one. However, sometimes accounts get closed or reopened and sometimes they may even get updated. I would like to assign a version Number for each new version of the account, which is made possible through the AccountCreatedDate. So anytime the account is created or updated it provides us with an AccountCreatedDate. So the oldest AccountCreatedDate should get a version number 1, the next should get number 2 and so on. How can this be done please provide code on how to accomplish this. I have provided code that groups the same accounts together as the same account will have the same TimeID and I have them in ascending order. How can I give them version numbers? Each record does have its own identity value known as InputRowID
Select * from ods.SchedulePayment
where TimeID IN(
Select TimeID
FROM ods.SchedulePayment
GROUP BY TimeID
HAVING COUNT(*) >1
)ORDER BY TimeID, AccountCreatedDate
I think you want row_nubmer():
select sp.*,
row_number() over (partition by TimeID order by AccountCreatedDate) as version_number
from ods.SchedulePayment sp;
If you want to update the value, then:
with toupdate as (
select sp.*,
row_number() over (partition by TimeID order by AccountCreatedDate) as new_version_number
from ods.SchedulePayment sp
)
update toupdate
set version_number = new_version_number
where version_number <> new_version_number or version_number is null;
Row_number() is what you should opt for
Select *, row_number() over (partition
by
Account order by accountcreationdate
asc) from ods.SchedulePayment
where TimeID IN(
Select TimeID
FROM ods.SchedulePayment
GROUP BY TimeID
HAVING COUNT(*) >1
)ORDER BY TimeID,
AccountCreatedDate

SQL server - SELECT a columns entry on a CASE WHEN query

I'd like to find out the first provider (PROVIDER_ID) to the client (CLIENT_ID) in a database table of bookings (BOOKING_ID)
I currently SELECT the CLIENT_ID first, then calculate various other things.
I group by (CLIENT_ID) and the count is correct.
What I'm looking for is
SELECT case when(min(BOOKING_ID)) then PROVIDER_ID else null end)
But I am unable to perform sub queries within the SELECT/CASE WHEN
I hope this makes sense and the question is clear.
Ideally I would like a solution that is within a single SELECT
Assuming you want to get the PROVIDER_ID for the MIN(BOOKING_ID) grouping by CLIENT_ID the following should work:
SELECT
Client_ID,
Booking_ID,
Provider_ID
FROM (
SELECT
Client_ID,
Provider_ID,
Booking_ID,
ROW_NUMBER() OVER (PARTITION BY Client_ID ORDER BY Booking_ID) as RowNumber
FROM
Bookings
) OrderedTable
WHERE
OrderedTable.RowNumber = 1
How does it work? ROW_NUMBER OVER (ORDER BY field) gives you the row number if the result set was ordered by a particular field. The PARTITION BY field allows you to partition the table by a particular key (in this case Client_ID) that will reset the ROW_NUMBER for each Client_ID (so if RowNumber = 1, it's the first entry for that particular client)
More details here: http://msdn.microsoft.com/en-us/library/ms186734.aspx
Using WITH syntax:
WITH OrderedTable AS
(
SELECT
Client_ID,
Provider_ID,
Booking_ID,
ROW_NUMBER() OVER (PARTITION BY Client_ID ORDER BY Booking_ID) as RowNumber
FROM
Bookings
)
SELECT
Client_ID,
Provider_ID,
Booking_ID
FROM
OrderedTable
WHERE
RowNumber = 1

How to write a derived query in Netezza SQL?

I need to query the data for inviteid based. For each inviteid I need to have the top 5 IDs and ID Descriptions.
I see that the query I wrote is taking all the time in the world to fetch. I didn't notice an error or anything wrong with it.
The code is:
SELECT count(distinct ID),
IDdesc,
inviteid,
A
FROM (
SELECT
ID,
IDdesc,
inviteid,
RANK() OVER(order by invtypeid asc ) A
FROM Fact_s
--WHERE dateid ='26012013'
GROUP BY invteid,IDdesc,ID
ORDER BY invteid,IDdesc,ID
) B
WHERE A <=5
GROUP BY A, IDDESC, inviteid
ORDER BY A
I'm not sure I understood you requirement completely, but as far as I can tell the group by in the derived table is not necessary (just as the order by as Mark mentioned) because you are using a window function.
And you probably want row_number() instead of rank() in there.
Including the result of rank() in the outer query seems dubious as well.
So this leads to the following statement:
SELECT count(distinct ID),
IDdesc,
inviteid
FROM (
SELECT ID,
IDdesc,
inviteid,
row_number() OVER (order by invtypeid asc ) as rn
FROM Fact_s
) B
WHERE rn <= 5
GROUP BY IDDESC, inviteid;