How to get date from closest old record for the given customer if a new one appears - sql

I am dealing with policy records table inside Google BigQuery. My table has three columns: INDVDL_ID, POLICY_ID and CNV_DT. Every unique client is identified with INDVDL_ID and may have one or more records in the table depending on how many policies he has. Each policy has it's id (POLICY_ID) and the date that it was bought (CNV_DT). So the code for pulling the data that I am using looks like that:
SELECT INDVDL_ID, POLICY_ID, CNV_DT
FROM `Policy_table.TP_Policies.policy_20191023
What I have:
<table><tbody><tr><th>INDVDL_ID</th><th>POLICY_ID</th><th>CNV_DT</th></tr><tr><td>1</td><td>1</td><td>2008-01-01</td></tr><tr><td>1</td><td>2</td><td>2008-04-31</td></tr><tr><td>1</td><td>3</td><td>2008-12-23</td></tr><tr><td>3</td><td>4</td><td>2009-08-19</td></tr><tr><td>2</td><td>5</td><td>2010-06-12</td></tr><tr><td>2</td><td>6</td><td>2011-11-12</td></tr></tbody></table>
What I would like to pull is table, where for every additional policy that customer has bought I can have a CNV_DT of his prior purchase.
What I would like to have:
<table><tbody><tr><th>INDVDL_ID</th><th>POLICY_ID</th><th>CNV_DT</th><th>PRIOR_CNV_DT</th></tr><tr><td>1</td><td>1</td><td>2008-01-01</td><td> </td></tr><tr><td>1</td><td>2</td><td>2008-04-31</td><td>2008-01-01</td></tr><tr><td>1</td><td>3</td><td>2008-12-23</td><td>2008-04-31</td></tr><tr><td>3</td><td>4</td><td>2009-08-19</td><td> </td></tr><tr><td>2</td><td>5</td><td>2010-06-12</td><td> </td></tr><tr><td>2</td><td>6</td><td>2011-11-12</td><td>2010-06-12</td></tr></tbody></table>

You seem to want lag():
SELECT INDVDL_ID, POLICY_ID, CNV_DT,
LAG(CNV_DT) OVER (PARTITION BY INDVDL_ID ORDER BY CNV_DT) as PRIOR_CNV_DT
FROM `Policy_table.TP_Policies.policy_20191023;

Related

How to get a row with no value in sql

I have a table with every campaign, that table has it's name and the number of emitted coupons. The table client_campaign connects the campaign with the client (campaign_id and client_id), so if a client subscribes a campaign, he gets a coupon.
I want to get a query with the number of emitted and used coupons. I started of with this:
select name, emitted_coupons, count(campaign_id) as used_coupons
from campaign, client_campaign
where campaign.campaign_id = client_campaign.campaign_id
group by name, emitted_coupons;
The problem is that my implementation doesn't show the campaigns where no coupon was used. I would like to know if it's possible to do all this using only one query and not changing the tables.
This can be done by using the NULL keyword:
SELECT * FROM table_name WHERE value IS NULL;

Exchanging rows and columns in

I am looking for a way to somehow bring the information of different rows in to different/one column.
This is the problem:
Assume that I have 10 different sellers and 1000 buyers.
Currently this is how data structured (picture)
So for each sale, I have a row with the id of the seller and a buyer who bought something from him. What I want to have is to have 1 row for each seller and then in one/different columns I want to see the id of the buyer.
I am using snowflake and read about different ways but none of them really works.
I also have a timestamp column in this table and the only thing that I could think up until now is to
SELECT seller,
rank()over(partition by seller order by purchase_date desc)
and after that I can use aggregation functions - this is not really a wise solution and not really practical when I have 10 -20 or more buyers.
What is the best approach for solving these types of problems?
You should be able to do this using listagg function as per the snowflake documentation
https://docs.snowflake.com/en/sql-reference/functions/listagg.html
--This will create a concatenated list of buyers seperated by a comma
select seller
,listagg(buyer,',') within group(order by buyer)
from table
group by seller

How to get unique customer names those have different IDS

I am working with a table that contains Account_No as unique ID, Customer_Name, Building_Name. The table below is an example:
It can be seen for few cases there are same customer name and same building however different Account_No. I need to remove duplicate names even though they have unique Account_No. Building_Name and Customer_Name are ties together. For example "William----Science City" and "William-----River Club" should be count as two customers since they are residing in different buildings. The result table should look as below;
I need to use SQL for creating the resulting table. Kindly use Customer Table as the reference for SQL query. Thanks
Select Min(Account_No) As Account_No
,Customer_Name,Building_Name
From Customer_Table
Group By Customer_Name, Building_Name

Return All Historical Account Records for Accounts with Change in Corresponding Value

I am trying to select all records in a time-variant Account table for each account with a change in an associated value (e.g. the maturity date). A change in the value will result in the most recent record for an account being end-dated and a new record (containing a new effective date of the following day) being created. The most recent records for accounts in this table have an end-date of 12/31/9000.
For instance, in the below illustration, account 44444444 would not be included in my query result set since it hasn't had a change in the value (and thus also has no additional records aside from the original); however, the other accounts have multiple changes in values (and multiple records), so I would want to see those returned.
I've tried using the row_num function, as well as a reflexive join, but for some reason I'm not getting the expected results. What are some ways to obtain the results I need?
Note: The primary key for this table includes the acct_id and eff_dt. Also, I'm using PostgreSQL in a Greenplum environment.
Here are two types of queries I tried to use but which produced problematic results:
Query 1
Query 2
If you want only the accounts, use aggregation:
select acct_id
from t
group by acct_id
having min(value) <> max(value);
Based on your description, you could also use count(*) >.
If you want the original records, you can use window functions:
select t.*
from (select t.*, count(*) over (partition by acct_id) as cnt
from t
) t
where cnt > 1;

Create dynamic Metric, which will be based on various dimensions/ filters applied

I have a table "Trans" which contains the acccountNumbers and other dimensions like Facility , Status etc.
I need to create a calculated member in SSAS where the logic would be
Count of Accounts in a group / Total accounts.
Count of Accounts in a group would be based on the Dimension filter I provide.
For e.g. If I provide the facility then I need the Count of accounts (In numerator) group be different facilities.
Likewise If I provide the Status I would need the numerator to be grouped as per the data in Status table.
Table Name
Trans (AccountNumber, facility,Status) -- This is fact table
Dimension tables
Facility( Id, Facility_name)
Status (Id, Status)
Not sure how to go about it.
EXISTING is a useful function, so maybe something like:
COUNT(
EXISTING [AccountNumber].[AccountNumber].MEMBERS
)