I would like to create a scatterplot or bubble graph that will show one point for an employee's annual salary based on total years worked for the company and compare it to all of the other employees.
However, the employee logging in will only be able to see detailed information about their point. All other points need to be anomymized.
I have a control table of employees that is using RLS with a user role.
when the user logs in, They can only see their salary data from other tables joined to the employee control table.
I would like to add a table with all other employee's salary info without their Employee IDs, Names, ETC to display all in a scatter plot.
Thanks.
Building on what is shown in this post by Darren Gosbell1, here is a suggestion for you. My model involves three tables, one with the interesting information and two which are the employee dimension, vertically partitioned into public and private columns.
Salary & Experience =
DATATABLE(
"Employee ID", INTEGER, "Salary", CURRENCY, "Experience", INTEGER,
{
{1, 100000, 20},
{2, 80000, 5},
{3, 75000, 0},
{4, 120000, 6},
{5, 45000, 35}
}
)
Employees (Public) =
DATATABLE(
"Employee ID", INTEGER, "Sex", STRING,
{
{1, "F"},
{2, "M"},
{3, "F"},
{4, "M"},
{5, "F"}
}
)
Employees (Private) =
DATATABLE(
"Employee ID", INTEGER, "Name", STRING,
{
{1, "Me"},
{2, "Fred"},
{3, "Sally"},
{4, "Bob"},
{5, "Irene"}
}
)
We just then set up one-to-many relationships between 'Employees (Public)' -> 'Salary & Experience' and 'Employees (Public)' -> 'Employees (Private)' using the [Employee ID] column.
We can create some roles which filter the 'Employees (Private)' table based on the identity of the current user.
Then we make the scatter plot as you described, being careful to use a unique attribute from the public partition of the employees table as the details for the plot. Note that when viewing as employee "Me" I can see name of that employee, but not another employee.
I'm sure that your filter you define in the roles will me more interesting than mine.
1: Which describes a theoretical implementation of column-level security in SSAS tabular using vertical partitioning.
Related
This question is a follow-up to another SO question.
This is for an e-commerce platform to show the end-user sales reports. I have a table ORDERS and a table ORDER_ITEMS. The data is received through a REST API as a JSON response. The JSON is synced through APEX REST Data Source and added to the local tables via a PLSQL trigger.
Sample JSON response
[
{
"order_id": "ZCHI8-N9Zm-VJ1o",
"order_number": 89653,
"order_date": "2023-01-01",
"store_id": 1,
"full_name": "Amalee Planque",
"email": "aplanque0#shinystat.com",
"city": "Houston",
"state": "Texas",
"zip_code": "77040",
"credit_card": "5048378382993155",
"order_items": [
{
"line_number": 1,
"product_id": 4,
"quantity": 1,
"price": 3919.8
},
{
"line_number": 2,
"product_id": 6,
"quantity": 1,
"price": 3089.36
},
{
"line_number": 3,
"product_id": 1,
"quantity": 1,
"price": 3474.4
}
]
},
{
"order_id": "XZnQx-PwYR-zWy2",
"order_number": 37946,
"order_date": "2022-01-29",
"store_id": 2,
"full_name": "Marillin Gadie",
"email": "mgadie1#comsenz.com",
"city": "Cleveland",
"state": "Ohio",
"zip_code": "44191",
"credit_card": "5108757233070957",
"order_items": [
{
"line_number": 1,
"product_id": 5,
"quantity": 1,
"price": 3184.37
}
]
},
]
Trigger to insert the order_items to the ORDER_ITEMS table
create or replace trigger "TR_MAINTAIN_LINES"
AFTER
insert or update or delete on "ORDERS_LOCAL"
for each row
begin
if inserting or updating then
if updating then
delete ORDER_ITEMS_LOCAL
where order_id = :old.order_id;
end if;
insert into ORDER_ITEMS_LOCAL ( order_id, line_id, line_number, product_id, quantity, price)
( select :new.order_id,
seq_line_id.nextval,
j.line_number,
j.product_id,
j.quantity,
j.price
from json_table(
:new.order_items,
'$[*]' columns (
line_id for ordinality,
line_number number path '$.line_number',
product_id number path '$.product_id',
quantity number path '$.quantity',
price number path '$.price' ) ) j );
elsif deleting then
delete ORDER_ITEMS_LOCAL
where order_id = :old.order_id;
end if;
end;
The ORDERS table contains all the order fields (order_id, order_number, etc.) It also contains order_items as a JSON array. (which gets extracted into the ORDER_ITEMS table by the trigger)
ORDERS table
ORDERS table data
The ORDER_ITEMS table contains all the order item fields (line_number, quantity, price). It also contains the order_id to reference which order the line item is referring to.
ORDER_ITEMS table
ORDER_ITEMS table data
I need to add an ORDER_TAX column to the ORDERS table. In which:
Grabs the order_items from the ORDER_ITEMS table which has the same order_id.
Adds all the price columns to get the total.
Multiply the total by 0.15 to simulate the estimated sales tax
Insert the 'sales tax' into the ORDER_TAX column in the ORDERS table.
I've created the ORDER_TAX column. I think I need to create a new trigger for this but I'm not quite sure how to code this out. I also need to create an ORDER_TOTAL column to the ORDERS table but I think I can figure that out once someone helps me with this initial question.
-----------UPDATE--------------
Per Koen's comment, it seems I need to actually create a view for this instead of a trigger.
The SQL query below returns the expected results
select ORDER_ID, SUM(PRICE) * 0.15 AS ORDER_TAX
from ORDER_ITEMS_LOCAL
GROUP BY ORDER_ID
How do I create a view so it inserts the value into the ORDERS table, ORDER_TAX column?
Per Koen's comment, I've been able to figure this out.
Go to Object Browser Create View
select
ORDERS_LOCAL.*,
A2.TAX,
A2.SUBTOTAL,
A2.TOTAL
from ORDERS_LOCAL
inner join (
select
ORDER_ID,
cast(sum(price) *0.15 as decimal(10,2)) as tax,
sum(price) as subtotal,
cast(sum(price) *1.15 as decimal(10,2)) as total
from ORDER_ITEMS_LOCAL
group by ORDER_ID
) A2
ON ORDERS_LOCAL.ORDER_ID=A2.ORDER_ID;
I then created a Master Detail report with the view as the source.
I have multiple simple calculated measures, which I would like to combine into categories, so that one could use this "category measure" in matrix visual.
Each measure basically counts data with some filter(s), like:
Blue =
CALCULATE(
COUNT(data[Full name]),
FILTER(data, data[White/Blue] = "Blue")
)
My attempt to this, was to create a table for measures categories, and then measure indexed accordingly.
Table:
Measures categories =
DATATABLE (
"Category", STRING,
"Sub-Category", STRING,
"Index", INTEGER,
{
{ "Direct/Indirect", "Direct", 1},
{ "Direct/Indirect", "Indirect", 2},
{ "White/Blue", "White", 3},
{ "White/Blue", "Blue", 4}
}
)
Measure:
Categories measure =
VAR SelectedMeasure_ =
SELECTEDVALUE('Measures categories'[Index])
RETURN
IF(HASONEVALUE('Measures categories'[Index]),
SWITCH(
SelectedMeasure_,
1, [Direct],
2, [Indirect],
3, [White],
4, [Blue]
)
)
This seems to work fine, however I'm missing Totals in Matrix visual, how do I get sum of measures per category/subcategory and total? I can workaround this by adding additional Total fields with corresponding sums, but there must be a better way.
One possible solution, is to create another measure, which sums value of Categories measure.
Your hasonevalue() looks like the problem. You need to rethink your approach to use values() but hard to advise further without a .pbix or full sample data to work from.
I'd likt to ask the way of grouping caategories. I knew that can use the Group function.
But my question is about duplicated values.
For example, There's column A,B,C,D,E in one table, but i want to make the bar graph as A, B&C, C&D ,E
Thank you for your time :)
I tried use group function, but since I group the Column B&C, It is not allow to gorup as C&D.
Create the following calculated table that contains your grouping logic
Groups =
DATATABLE(
"Group", STRING,
"Category", STRING,
{
{"A", "A"},
{"B & C", "B"},
{"B & C", "C"},
{"C & D", "C"},
{"C & D", "D"},
{"E", "E"}
}
)
Next you create a one-to-many relation between the Categories with the filter direction set to "Both" (bi-directional)
Finally you can create your visuals with the overlapping grouping
I have a model that I run a daterange query over. For business reasons, I annotate a field in my results that represent CST timezone (data is stored in UTC by default).
The query below returns an empty queryset even though there are entries by the date range mentioned below.
MyModel.objects.annotate(cst_created_at=ExpressionWrapper(F('created_at')-timezone.timedelta(hours=6, minutes=0), output_field=DateTimeField())).filter(cst_created_at__date__range=["2022-09-01", "2022-09-01"])
If I get the values of cst_created_at (that I annotated) and created_at, which is a auto_now_add=True field, they're both the same.
result = MyModel.objects.annotate(cst_created_at=ExpressionWrapper(F(field)-timezone.timedelta(hours=6, minutes=0), output_field=DateTimeField())).first()
cst = result.cst_created_at
ca = result.created_at
print(cst)
>>>datetime.datetime(2022, 9, 1, 0, 51, 2, 310752, tzinfo=<UTC>)
print(ca)
>>>datetime.datetime(2022, 9, 1, 6, 51, 2, 310752, tzinfo=<UTC>)
cst.date() == ca.date()
>>>True
At the same time, if I query cst_created_at with yesterday's date (2022-08-31) it returns the objects created on 2022-09-01. Also, if I query created_at__date for 2022-09-01 it works as well.
I wanna know if both the dates are same why doesn't the query work properly?
I have data in the PowerBI which I need to crosstab in order to generate the base data for a specific visual.
Example data:
tblExample = DATATABLE("Customer ID", INTEGER, "Gender", STRING, "Age Range", STRING, "Order Date", DATETIME, "WS Next Day", STRING, "Order Next Day", STRING, "WS Next Week", STRING, "Order Next Week", STRING, "WS Next Month", STRING, "Order Next Month", STRING,
{
{1, "Female", "30 - 39", "2017-02-09", "Yes", "No", "Yes", "No", "No", "No" },
{2, "Female", "30 - 39", "2017-02-11", "Yes", "Yes", "Yes", "No", "No", "No" },
{3, "Female", "50 - 59", "2017-02-12", "Yes", "No", "Yes", "No", "No", "No" },
{4, "Male", "20 - 29", "2017-02-12", "Yes", "No", "Yes", "No", "No", "No" },
{5, "Male", "40 - 49", "2017-02-19", "No", "No", "Yes", "No", "No", "No" }
}
)
This data shows customers who have placed an order and then a set of six yes / no flags showing whether or not the customer has visited the web site again the following day / week / month, and whether this visit resulted in another order.
What I need to do is turn this information into a table with one row for each category of "Next Day", "Next Week" and "Next Month", and for each row a value showing the count of customers who (a) visited and (b) purchased.
I thought this would be pretty straight forward to do in DAX - and to be honest I'm not sure that it isn't and I haven't just missed something really obvious - but at the moment I can't see a tidy way to achieve this.
I have created measures for each of the six values I need as follows:
NextDay_Visits = COUNTROWS(FILTER(tblExample, [WS Next Day] = "Yes"))
NextDay_Orders = COUNTROWS(FILTER(tblExample, [Order Next Day] = "Yes"))
And so on, and when I look at these measures in a card they give me the correct values, but to jam these into a table which is the correct shape I do the following (which is almost certainly the wrong way to do this in PowerBI !):
1 Create a new table
tblJunk1 = DATATABLE("Row ID", INTEGER, "Category", STRING, { {1, "Next Day"} })
2 Add the appropriate measures to the new table as new columns
tblJunk2 = ADDCOLUMNS(tblJunk1, "Visits", [NextDay_Visits], "Purchases", [NextDay_Purchases])
3 Do the same two steps again using tblJunk3 / tblJunk4 for the "Next Week" figures
4 Do the same two steps again using tblJunk5 / tblJunk6 for the "Next Month" figures.
5 Create a final table to use as the basis for my column chart by union-ing tblJunk2 / tblJunk4 / tblJunk6
tblChartBase = UNION(tblJunk2, tblJunk4, tblJunk6)
Then it's good news / bad news, because although this seems to me to be a horrible hack solution, I do get the table I need with the correct figures and the correct shape, and I can base a column chart on it which gives me the analysis I am looking for. (Good News!)
However, once I add slicers to the page based on "Gender" and "Age Group", the measures in this new table do not respond to them and the figures do not change meaning that this is not the way to achieve what I want. (Bad News)
I am not sure whether I am kind of hedging around the correct methodology but need to tweak my DAX for the measures so they do respond to the slicers on the page, or whether this is totally the wrong approach from the ground up?
Any suggestions / pointers gratefully received.
I would address this requirement in the Query Editor. It has Unpivot functionality that should meet your needs, e.g.
https://support.office.com/en-us/article/unpivot-columns-power-query-0f7bad4b-9ea1-49c1-9d95-f588221c7098
The Query Editor has added a few more options since that article was written, like Unpivot Other Columns, Unpivot Only Selected Columns.