SQL help to insert unique values - sql

I need to insert the Unique combination of Ticker, Dividend_Pay_Date to another table. If I find duplicate data I need to select only the Dividend_type_marker_description = 'Final' row. I am showing example of source data where I have duplicate data for Ticker ABC.
I have noticed Dividend_type_marker_description = '2nd Interim' also for same date-ticker combination. But no more than 3 status
I would appreciate any help with this.

I think row_number() does what you want:
select . . .
from (select t.*,
row_number() over (partition by ticker, dividend_pay_rate
order by (case when Dividend_type_marker_description = 'Final' then 1 else 2 end)
) as seqnum
from t
) t
where seqnum = 1;

Related

How to select distinct records with preference depending on a value

i have this table :
Table 1
notice that some ids have double records with IsTop = 1
if i have this kind of scenario im interested in selecting the one that has IsTop = 1 and if i dont im interested in keeping the one that IsTop = 0.
The goal is to have distinct Id's but take IsTop = 1 is it exists.
How do i do that?
You can use row_number():
select t.*
from (select t.*,
row_number() over (partition by id order by isTop desc) as seqnum
from t
) t
where seqnum = 1;

Transposing Rows into Multiple columns SQL Server

I have a table with multiple rows that needs transposed to one row with multiple columns. The order in which the items are listed on my current table matters for ranking purposes, so I need them to stay in order when they are transposed into columns
Thanks in advance
You can use row_number() & do conditional aggregation :
SELECT individuaid,
MAX(CASE WHEN seq = 1 THEN item_no END) item_no_1,
MAX(CASE WHEN seq = 1 THEN HL2_CODE END) HL_2_1,
. . . .
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY individuaid ORDER BY item_no) AS seq
FROM table t
) T
GROUP BY individuaid;

Organizing SQL data based on date

I am trying to organize my SQL data based off of the dates from which the orders were made.
My data:
SELECT DISTINCT ORDER_NO, ITEM, VERSION_NO,
(CASE WHEN ROW_NUMBER() OVER (PARTITION BY ORDER_NO ORDER BY NOT_BEFORE_DATE
ASC) = 1
THEN 'what-if'
ELSE 'wh'
END) AS VERSION_NEW
,
(CASE WHEN ROW_NUMBER() OVER (PARTITION BY ORDER_NO ORDER BY
NOT_BEFORE_DATE ASC) = 2
THEN 'initial'
ELSE 'other'
END) AS VERSION
FROM FDT_MAPTOOL
WHERE ITEM IN (1032711)
;
My results:
I want my data to be ordered by PO# and the date it was created.
As you can see in my picture the First two line have the same ITEM and same PO (Order_No). I need the first two to say Initial on the side because they are the first two based on the dates. They were created first. Everything after should say other.
I am not sure if PL/SQL is needed for this?
Thank you!
Use a different analytic function so that more than one row can have the value of 1 e.g.
SELECT DISTINCT ORDER_NO, ITEM, VERSION_NO,
(CASE WHEN DENSE_RANK() OVER (PARTITION BY ORDER_NO ORDER BY NOT_BEFORE_DATE
ASC) = 1
THEN 'what-if'
ELSE 'wh'
END) AS VERSION_NEW
,
(CASE WHEN DENSE_RANK() OVER (PARTITION BY ORDER_NO ORDER BY
NOT_BEFORE_DATE ASC) = 1
THEN 'initial'
ELSE 'other'
END) AS VERSION
FROM FDT_MAPTOOL
WHERE ITEM IN (1032711)
;
Either rank() OR dense_rank() should work here instead of row_number()
nb: note sure if you really need "select distinct"

How to join a table to itself using rank multiple times?

I apologize if there is an existing solution, I tried searching quite a bit but couldnt find much.
Here's what I am trying to do:
I have a table that resembles the first image. I want it to look like the second image. Basically every time rnk_address = 1, I want that row's order_date to be moved into a separate column for that associated user_id.
I'm ultimately trying to calculate the average difference in order_date between all rnk_address = 1, by user_id.
I added a user_counter column using rank because I imagine I will need to do some time of join where i do user_rank = user_rank + 1? But not sure....
Original table:
End result:
You can use conditional aggregation:
select user_id, first_name,
max(case when seqnum = 1 then order_date end) as order_date_1,
max(case when seqnum = 2 then order_date end) as order_date_2,
max(case when seqnum = 3 then order_date end) as order_date_3
from (select t.*,
row_number() over (partition by user_id order by order_date) as seqnum
from t
where rnk_address = 1
) t
group by user_id, first_name;

SQL Teradata - Adding Column of first row data and so on w/ restrictions

Goal: Take the current row of the table and find the most recent item of that customer and append that item data in the next column. If the most recent item is the item 1 of that row then it should proceed to the next row. The logic should always go the the very first row of that customer. Order is based on Transaction Date and partitioned by customer ID. Example of base data provided below in addition to what the desired result set should look like after running the script.
Restrictions: I need this script to work in a CRM tool. Specifically Aprimo/CIM by teradata. With that being said I cannot use CTEs (With) or volatile tables. I also do not want to create multiple joins into itself because of the table volume.
What I have done Thus Far: I feel that the best approach may be to utilize the Window Function, but finding myself creating a lot of nested case statements. I really wanted to know if there was a better way to get the answer i am looking for. I might have to just suck it up and do a join into itself.
Base table
Desired Result Set
Quick Start Base Table:
CREATE VOLATILE TABLE Base
(
customer_id int
, trans_date date
, item varchar(1)
) ON COMMIT PRESERVE ROWS;
Insert Into Base (123,'2017-01-01','A');
Insert Into Base (123,'2017-01-02','B');
Insert Into Base (123,'2017-01-03','C');
Insert Into Base (123,'2017-01-04','D');
Insert Into Base (123,'2017-01-05','E');
Insert Into Base (999,'2017-01-06','F');
Insert Into Base (999,'2017-01-07','G');
Insert Into Base (999,'2017-01-08','H');
There's some CASEs, but not lots :-)
SELECT
dt.*,
CASE
WHEN rn = 1
THEN Min(CASE WHEN rn = 2 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 1 THEN item end) Over (PARTITION BY customer_id)
END,
CASE
WHEN rn <=2
THEN Min(CASE WHEN rn = 3 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 2 THEN item end) Over (PARTITION BY customer_id)
END,
CASE
WHEN rn <= 3
THEN Min(CASE WHEN rn = 4 THEN item end) Over (PARTITION BY customer_id)
ELSE Min(CASE WHEN rn = 3 THEN item end) Over (PARTITION BY customer_id)
END
FROM
(
SELECT
Row_Number() Over (PARTITION BY customer_id ORDER BY trans_date) AS rn
,base.*
FROM Base
) AS dt
ORDER BY customer_id, trans_date