PowerPivot DAX - Creating column based on most common value in another column - dax

I have a table in my Power Pivot model that includes customer IDs, account IDs, and sales for a bunch of transactions. The problem is that some account IDs are missing.
For any record with a missing account ID, I want to populate it with the most common account ID for the customer (based on sales).
Cust_ID
Acct_ID
Sales
225
ABC
10
225
ABC
50
225
DEF
0
225
10
225
20
588
XYZ
500
So for Customer 225, the most common Account ID (based on sales) is ABC. I'd want to add a column like this.
Cust_ID
Acct_ID
Sales
Final_Acct_ID
225
ABC
10
ABC
225
ABC
50
ABC
225
DEF
0
ABC
225
10
ABC
225
20
ABC
588
XYZ
500
XYZ

Final_Acct_ID =
VAR tbl =
CALCULATETABLE(
FILTER(
ADDCOLUMNS(
SUMMARIZE( 'Table1', 'Table1'[Cust_ID], 'Table1'[Acct_ID]),
"#count",
CALCULATE( COUNT('Table1'[Acct_ID]))
),
'Table1'[Acct_ID] <> BLANK()
),
ALLEXCEPT('Table1','Table1'[Cust_ID]))
RETURN
MAXX(TOPN(1,tbl,[#count]), 'Table1'[Acct_ID])

Related

write function which will display train details having maximum passanger for given date?

following are the table in database.
many to many relations between train and passenger
table 1 name=train
TNO TNAMe
1 x
2 y
3 z
table 2 name=passenger
PNO PNAME
111 a
222 b
333 c
table 3 name=tp
TNO PNO TPDATE
1 111 23-NOV-15
2 222 24-JUN-14
3 222 19-JUN-13
1 333 23-NOV-15
using follwing code i only find out which train number has highest frequency
select tno,count(tno) as numberofoccurance from tp group by tno
Try to use group by and row_number analytical function as following:
Select name, tp_date
From
(Select t.tname tp.tp_date,
row_number() over (partition by tp.tp_date order by count(1) desc nulls last) as cnt
From train t
Join tp tp
On (t.id = tp.tno)
Group by tp.tno, tp.tp_date)
Where cnt = 1;
Cheers!!

PIVOT table in Oracle

Can you help me to pivot the details in my Oracle table PAY_DETAILS
PAY_NO NOT NULL NUMBER
EMP_NO NOT NULL VARCHAR2(10)
EMP_ERN_DDCT_NO NOT NULL VARCHAR2(21)
ERN_DDCT_CATNO NOT NULL VARCHAR2(10)
ERN_DDCT_CATNAME NOT NULL VARCHAR2(1000)
PAY_MONTH NOT NULL DATE
AMOUNT NOT NULL NUMBER(10,2)
EARN_DEDUCT NOT NULL VARCHAR2(2)
select EMP_NO,EMP_ERN_DDCT_NO,AMOUNT,EARN_DEDUCT, ERN_DDCT_CATNO from pay_details
EMP_NO EMP_ERN_DDCT_NO AMOUNT EA ERN_DDCT_C
---------- --------------------- ---------- -- ----------
219 10 175 A 001
219 1 5000 A 002
794 7 50000 A 001
769 6 35000 A 001
465 4 5000 A 002
289 2 5000 A 002
435 3 5000 A 002
816 38 5 D 201
737 30 5 D 201
Is it possible to make this output into a cross tab?
So, lets assume you want to pivot your salary data for each month. You can use the following query.
SELECT * FROM
(
SELECT emp_no,
emp_ern_ddct_no,
pay_month,
amount
FROM pay_details
)
PIVOT
(
SUM(amount)
FOR pay_month IN ('01/01/2016', '02/01/2016', '03/01/2016','04/01/2016','05/01/2016','06/01/2016','07/01/2016','08/01/2016','09/01/2016','10/01/2016','11/01/2016','12/01/2016')
)
ORDER BY emp_no;
This is just an example, you can PIVOT your data based on different columns. For more details refer to the following link.
http://www.techonthenet.com/oracle/pivot.php
http://www.oracle-developer.net/display.php?id=506
Since you are on Oracle 10g PIVOT wont work. Try using something similar to the below query.
SELECT emp_no,
SUM(CASE WHEN pay_month ='01/01/2016' THEN AMOUNT ELSE 0 END) jan_pay,
SUM(CASE WHEN pay_month ='02/01/2016' THEN AMOUNT ELSE 0 END) feb_pay,
SUM(CASE WHEN pay_month ='03/01/2016' THEN AMOUNT ELSE 0 END) march_pay
.........
FROM pay_details
GROUP BY emp_no;

How do I get both the child and one upper level parent information by using oracle connect by prior?

I want to get both the child and one upper level parent information by using oracle connect by prior?
For example the folowing query retrieve child info and parent id,
SELECT last_name, employee_id, manager_id, LEVEL
FROM employees
START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id
but I want to get parent info also like
LAST_NAME EMPLOYEE_ID MANAGER_ID LEVEL MANAGER_NAME
------------------------- ----------- ---------- ----------------------------
King 100 1 ?
Cambrault 148 100 2 ?
Bates 172 148 3 ?
Bloom 169 148 3 .
Fox 170 148 3 .
How can I handle this problem, when I applied left join after selecting childs by connect by prior,The objects order is mixing.
You can refer to prior values in the select list:
SELECT last_name, employee_id, manager_id, LEVEL, prior last_name as manager_name
FROM employees
START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id;
LAST_NAME EMPLOYEE_ID MANAGER_ID LEVEL MANAGER_NAME
------------------------- ----------- ---------- ---------- -------------------------
King 100 1
Kochhar 101 100 2 King
Greenberg 108 101 3 Kochhar
Faviet 109 108 4 Greenberg
...
Cambrault 148 100 2 King
Bates 172 148 3 Cambrault
Bloom 169 148 3 Cambrault
Fox 170 148 3 Cambrault
...

Removing duplicate data from a column

I have a table with following structure
Id Pro_id name price
----------------------------------------
1 001 ABC 200
1 002 XYZ 100
1 003 XYZ 150
2 004 PQR 100
2 005 PQR 100
2 006 LMN 200
2 007 LMN 300
2 008 DEF 150
As you can see there are some duplicate names in 'name' column.
I want to remove all the duplicate names(just need to keep first entered name and remove remaining)
So my table should look like-
Id Pro_id name price
----------------------------------------
1 001 ABC 200
1 002 XYZ 100
2 004 PQR 100
2 006 LMN 200
2 008 DEF 150
I tried following to get duplicate names-
SELECT ID, NAME, count(NAME) FROM TABLENAME
GROUP BY ID, NAME HAVING count(NAME)>1
But now I am unable to go further, stucked in how to delete the records.
any idea?
You may try below SQL (In MySQL it works)
delete t1.* from tablename t1
inner join
tablename t2 ON t1.name = t2.name
AND t1.Pro_id > t2.Pro_id
There is no "first" in SQL as the order of select is generally undefined, so the following will keep entries with the minimum value of Pro_id for duplicated names, but you are free to define a different aggregator:
DELETE FROM tablename
WHERE Pro_id NOT IN (SELECT MIN(Pro_id) FROM tablename GROUP BY name);
DELETE FROM table_name
WHERE rowid NOT IN
(
SELECT MIN(rowid)
FROM table_name
GROUP BY column1, column2, column3...
) ;
You can try something like this
delete from table1
where rowid in
(
select rid
from
(
select rowid as rid,
row_number() over (partition by name order by pro_id) as rn
from table1
)
where rn > 1
)
Havent tested it

inner join is correct or not for these tables?

create table dpt (
deptno number,
dname varchar2(10),
loc varchar2(7)
)
create table emp1 (
empno number,
ename VARCHAR2(10),
desigantion varchar2(10),
mgr number,
deptno number
)
result 1:
111 ram analyst 444 10
222 mohan clerk 333 20
333 hari manager 111 10
444 manju engineer222 30
result2:
10 inventory hyd
20 finance bglr
30 hr mumbai
Now inner joining these two tables:
select * from emp1 inner join dept on emp1.deptno=dept.deptno
result:
111 ram analyst 444 10 10 inventory hyd
222 mohan clerk 333 20 20 finance bglr
333 hari manager 111 10 10 inventory hyd
is it correct or not?
No. You will get four rows. Means entire rows in tables (If having a joining row in the other table as well) unless otherwise there is a filter to throw out.
See you data here
select *.emp1,*.dept from emp1,dept when emp1.deptno=dept.deptno

Resources