I have the data below in SQL.
DOB Status Policy StartDate EndDate
1/05/1983 Lapsed P1 5/05/2015 5/06/2016
1/05/1983 New Business P2 3/05/2016
2/04/1999 Lapsed P3 5/02/2016 10/06/2017
2/04/1999 New Business P4 10/07/2017
3/06/1972 Lapsed P5 6/07/2016 15/12/2017
3/06/1972 New Business P6 1/10/2017
4/12/1954 Lapsed P7 7/03/2017 1/03/2018
4/12/1954 New Business P8 1/03/2018
I need to add descending number based on DOB field. The expected result suppose to be like below.
Unfortunately I only can get number '1' in column #.
For column #, I have tried using index(), Window_Count (Countd(DOB), 04,0), Runnning_Total (Table Down, Pane Down, Specific Dimension : DOB), however nothing works.
I'm using Tableau desktop/server 10.0.
Thanks all for the help.
Use RANK_DENSE function:
"Returns the dense rank for the current row in the partition. Identical values are assigned an identical rank, but no gaps are inserted into the number sequence. Use the optional 'asc' | 'desc' argument to specify ascending or descending order. The default is descending.
With this function, the set of values (6, 9, 9, 14) would be ranked (3, 2, 2, 1)."
RANK_DENSE(SUM(FLOAT([DOB])),'asc')
Related
I have a table of policies with account number, effective, cancellation & expiration dates. I want to know how long an account had active policies for
Raw Table
id, account_id, effective_date, cancellation_date, expiration_date
1, a, 2020-01-01, null, 2020-06-01
2, b, 2020-02-01, null, 2020-07-01
3, b, 2020-03-01, null, 2020-08-01
4, a, 2020-04-01, null, 2020-09-01
5, b, 2020-04-01, 2020-08-15, 2020-09-01
Ideal output
account_id, active_date, inactive_date, active_time
a, 2020-01-01, 2020-09-01, 9 months
b, 2020-02-01, 2020-08-15, 7 months 15 days
So far I have made a table that has account_id as the left hand column. And then I have
MIN(effective_date) to get me the active date of the first policy.
Then I have Policy_Inactive_Date = MIN(cancellation_date, expiration_date). But that gives me the time the first policy was expired or cancelled.
It feels like I need to do MAX(Policy_Inactive_Date) but that throws and error.
I'm wondering if at first I need to get Policy_Inactive_Date at the policy level, and then get the max at the account level.
Do it like that
active_dt field like this
{
Fixed [account_id]: MIN([effective_date])
}
inactive_dt like this
{
Fixed [account_id]:MAX(IF ISNULL(MIN([cancellation_date],[expiration_date])) then [expiration_date] else MIN([cancellation_date],[expiration_date]) END)
}
Try MAX(MIN(cancellation_date, expiration_date))
There are two forms of MIN() -- and two forms of MAX(). With one argument, MIN() is an aggregation function, returning the least non-null value of that argument for a set of records. With two arguments, MIN() evaluates each argument and returns the smallest of those two values.
I have the following Episode table example:
Please note, where DischDate= "2020-02-20" means - client hasn't been discharged.
It's like NULL (this date meant to fill out NULL)
My goal is do display all possible overlaps within the same EHRClientFK, as following:
See the schema of my all possible Overlaps:
So, in this table's case I expect to display -
EHRClientFK / AdmDate / DischDate for only EHRClientFK = 2, 4, 3, 5 (which satisfies the schema):
This should be the resulting table:
EHRClientFK values 8,9,10 have no duplicate (overlaps), Clients 6, 7 have two adm-disch dates, but they
are NOT overlapping betw. each other
To achieve this result, I have the following code:
SELECT
a.[EHRClientFK]
,a.[AdmDate]
,a.[DischDate]
FROM [WH].[dbo].[Episode] a
INNER JOIN [WH].[dbo].[Episode] b ON a.EHRClientFK = b.EHRClientFK
WHERE
((a.DischDate = '2020-02-20') AND (b.DischDate = '2020-02-20'))
OR ((a.AdmDate < b.DischDate) AND (b.AdmDate < a.DischDate))
GROUP BY
a.[EHRClientFK]
,a.[AdmDate]
,a.[DischDate]
HAVING COUNT (*) >1
But, when I apply this on my original Table (with over 20K records) - I am still having non duplicate
EHRClientFK, like 8,9,10 (very insignificant amount, but still); and some cases of 6,7 with NO overlapping dates
How should I change my Where clause in order to satisfy my Overlap schema (to cover all overlap cases)"?
I have a table called Configuration. The 1st column of the table is deviceId, the 2nd column is parameter, 3rd column is value.
In the table, there are many devices, each device has only one device ID(column 1); each device has many config parameters(column 2), ex. VER, DATE, COMPANY etc, all devices have the same config parameters; the parameter's value(column 3) for different devices may be the same or not.
I want to update two config parameters say VER and DATE with new parameter's values(column 3) for the device which has ID equal to "id12345".
How can I achieve this in one PostgreSQL query?
This is what you could do, although I don't think it's a terrific idea.
UPDATE configuration
SET value =
CASE parameter
WHEN 'VER' THEN new_ver_value
WHEN 'DATE' THEN new_date_value
END
WHERE deviceid = 'id12345';
Parameter tables like this are generally considered a bad idea, as the complexity of this query helps illustrate. Also, since you say that all the devices have the same parameters, doing this instead of having a unique column for each parameter doesn't seem to achieve anything useful.
Also if possible use just a number for the deviceid instead of a string.
As requested, to update an additional field, like a time field set to the current_time, you could do the following.
UPDATE configuration
SET value =
CASE parameter
WHEN 'VER' THEN new_ver_value
WHEN 'DATE' THEN new_date_value
END,
time = current_time
WHERE deviceid = 'id12345'
AND parameter IN ('VER', 'DATE');
For the first query, here is a test to show the result.
CREATE TABLE configuration
(deviceid CHARACTER VARYING (20),
parameter CHARACTER VARYING (10),
VALUE integer);
INSERT INTO configuration
(VALUES ('id12345', 'VER', 1),
('id12345', 'DATE', 20190101),
('id12345', 'COMPANY', 55),
('id33333', 'VER', 2),
('id33333', 'DATE', 20180101),
('id33333', 'COMPANY', 6));
SELECT * FROM configuration;
id12345 VER 1
id1234 DATE 20190101
id12345 COMPANY 55
id33333 VER 2
id33333 DATE 20180101
id33333 COMPANY 6
UPDATE configuration
SET value =
CASE parameter
WHEN 'VER' THEN 11
WHEN 'DATE' THEN 2020010
END
WHERE deviceid = 'id12345'
AND parameter IN ('VER', 'DATE');
SELECT * FROM configuration;
id12345 COMPANY 55
id33333 VER 2
id33333 DATE 20180101
id33333 COMPANY 6
id12345 VER 11
id12345 DATE 2020010
I've ran into an issue that I cant seem to solve without a lot of changes deep in the code, and I think there must be a simpler solution that I'm simply not aware of.
I have a table of product names, product locations and various statuses (from 1 to 10). I have data for all products and locations but only some of the statuses (for example product X in city XX has data for categories 1 and 3, and product Y for city YY has data for categories 1 to 6).
I'd like to always display 10 repetitions of each product/location, with corresponding data (if there is any) or nulls. This makes a report I'm planning on creating much easier to read and understand.
I'm using SSMS2017, on SQL Server 2016.
SELECT
[Product],
[Location],
[Category],
[Week1],
[Week2],
[Week3]
FROM MyView
Naturally it will only return data that I have, but I'd like to always return all 10 rows for each product/location combination (with nulls in Week columns if I have no data there).
Your question ist not very clear, but I think, that my magic crystall ball gave me a good guess:
I think, that you are looking for LEFT JOIN and CROSS JOIN:
--Next time please create a stand-alone sample like this yourself
--I create 3 dummy tables with sample data
DECLARE #tblStatus TABLE(ID INT IDENTITY,StatusName VARCHAR(100));
INSERT INTO #tblStatus VALUES('Status 1')
,('Status 2')
,('Status 3')
,('Status 4')
,('Status 5');
DECLARE #tblGroup TABLE(ID INT IDENTITY,GroupName VARCHAR(100));
INSERT INTO #tblGroup VALUES ('Group 1')
,('Group 2')
,('Group 3')
,('Group 4')
,('Group 5');
DECLARE #tblProduct TABLE(ID INT IDENTITY,ProductName VARCHAR(100),StatusID INT, GroupID INT);
INSERT INTO #tblProduct VALUES ('Product 1, Status 1, Group 2',1,2)
,('Product 2, Status 1, Group 3',1,3)
,('Product 3, Status 3, Group 4',3,4)
,('Product 4, Status 3, Group 3',3,3)
,('Product 5, Status 1, Group 5',1,5);
--This will return each status (independent of product values), together with the products (if there is a corresponding line)
SELECT s.StatusName
,p.*
FROM #tblStatus s
LEFT JOIN #tblProduct p ON s.ID=p.StatusID
--This will first use CROSS JOIN to create an each-with-each cartesian product.
--The LEFT JOIN works as above
SELECT s.StatusName
,g.GroupName
,p.*
FROM #tblStatus s
CROSS JOIN #tblGroup g
LEFT JOIN #tblProduct p ON s.ID=p.StatusID AND g.ID=p.GroupID;
If this is not what you need, please try to set up an example like mine and provide the expected output.
My need is to display the numbers of customers who returned an order in a month "M" and placed a new order on the next 6 months after the month "M". And that has to be displayed in a bar chart in QlikSense.
I created a first measure with :
count(distinct [Account id])
then I added my condition on my order returned :
count(distinct ${<[Transactions Type] = {"RETURN"}>} [Account id])
So with that I get the numbers of customers who returned an order by month M ("Order Creation YearMonth").
I created a second measure with :
count(distinct [Account id])
then I added my condition on my order on the next 6 months :
Rangesum(above(count(distinct ${<[Transactions Type] = {"ORDER"}>} [Account id]), 0, 6))
So with that I get the numbers of customers who placed an order on the 6 next months after the month M ("Order Creation YearMonth").
In abscissa, I put my dimension "Order Creation YearMonth".
My problem is that I don't know how to merge these 2 measures in a set analyzis.
Do I have to use the p operator ?
Or the * operator to combine the 2 conditions on the "Transactions Type" ? But how can I add the rangesum ? Or maybe it is the wrong way ...
Thanks to any of you who can give me some tips to move forward on this crazy problem, my brain thanks you ! :)