Left Join also working in direct query in Power BI - join

This is only sample case, my original table is more complex.
Table A
SchoolId
ClubId
ChildID
TeacherId
AttendanceDate
IsPresent
A
1
1
1
22-MAY-2022
1
A
1
2
1
22-MAY-2022
0
A
1
3
1
22-MAY-2022
1
B
2
11
2
22-MAY-2022
1
B
2
22
2
22-MAY-2022
0
B
2
33
2
22-MAY-2022
0
Table B
ChildID
TeacherId
CreateOn
IsPresent
ReasonId
2
1
22-MAY-2022
0
1
2
1
23-MAY-2022
0
2
22
2
22-MAY-2022
0
2
33
2
22-MAY-2022
0
3
Table C
ReasonId
ReasonMaster
1
Health
2
Social
3
Unknown
I want the left join result like this :
SchoolId
ClubId
ChildID
TeacherId
AttendanceDate
IsPresent
ReasonId
ReasonMaster
A
1
1
1
22-MAY-2022
1
A
1
2
1
22-MAY-2022
0
2
Social
A
1
3
1
22-MAY-2022
1
B
2
11
2
22-MAY-2022
1
B
2
22
2
22-MAY-2022
0
2
Social
B
2
33
2
22-MAY-2022
0
3
Unknown
Here are my cases:
I only want to retrieve the latest data from table B based on create on column on the table B to the table A. Because there is a duplicate input by users. for instance in the table B child Id= 2 & Teacher Id=1.
I only need to retrieve the the data if the status in the table A, column IsPresent=0
There is an additional data from table C which reason master.
I try this Query, but CTE function not working in Power BI.
;with MaxCreate as (Select ChildID,TeacherID,Max(CreateOn) as MaxCreateOn
from TableB
group by ChildID,TeacherID)
,LatestCreate as (select TableB.ChildID, TableB.TeacherId, TableB.CreateOn, TableB.IsPresent, TableB.ReasonId
from TableB
inner join MaxCreate
on TableB.ChildID = MaxCreate.ChildID
and TableB.TeacherId = MaxCreate.TeacherId
and TableB.CreateOn = MaxCreate.MaxCreateOn)
Select
TableA.SchoolId
,TableA.ClubId
,TableA.ChildID
,TableA.TeacherId
,TableA.AttendanceDate
,TableA.IsPresent
,LatestCreate.ReasonId
,TableC.ReasonMaster
From TableA
Left join LatestCreate
on TableA.ChildID = LatestCreate.ChildID
and TableA.TeacherID = LatestCreate.TeacherID
left join TableC
on LatestCreate.ReasonId = TableC.ReasonId

Related

Count unique values across multiple columns

I have data in this format
A B C D
1 1 1 1
1 1 1 2
1 1 1 3
1 1 1 4
...
4 4 4 4
I want to count number of unique values in each row and print it
output:
A B C D unique-count
1 1 1 1 4
1 1 1 2 3
1 1 1 3 3
1 1 1 4 3
...
4 4 4 4 4

column =char(1), and also =char(0)

I have a table that includes a column foo.
show create table shows `foo` bit(1) DEFAULT b'0', so the column should contain binary strings: the 0 and 1 bytes.
select ascii(foo),
ord(foo),
foo=char(1),
foo=char(0),
char(1)=char(0)
from table_name
group by 1,2,3,4,5
yields
ascii(foo) ord(foo) foo=char(1) foo=char(0) char(1)=char(0)
0 0 1 1 0
1 1 0 0 0
I'd expect it to yield
ascii(foo) ord(foo) foo=char(1) foo=char(0) char(1)=char(0)
0 0 0 1 0
1 1 1 0 0
Can someone please explain what's going on?
Nor is this restricted to the select clause. It happens in the where clause also: select distinct ascii(foo) from table_name where foo=char(0) and select distinct ascii(foo) from table_name where foo=char(1) both return only 0.
select ##version
5.7.21-20-57-log

Dynamic QUERY range

I have a spreadsheet and in one of the tabs I have a table with computed data from other tabs. This is small table with 11 columns. Row(1) is the Header row and Column A is the list of items, Column B to J is the types. Data consists of numbers only.
As the data is computed, time to time values in some of the columns thru B to J can be totally zero. I want to create a subset of this table with QUERY but constructing a dynamic range getting only the columns which has at least 1 value which is greater than zero.
I'm aware that a range can be created as an array like {A:A\B:B\D:D} but in my case I don't know which columns can have values of greater than zero and I don't want to take columns into the range which has completely zero values.
I have created an expression to concatenate this array value as a text in a cell, however I can't use it with the QUERY formula either with INDEX or TEXT functions. Table is like this:
Items TypeA TypeB TypeC TypeD
Bronze 0 0 0 0
Silver 0 0 1 0
Gold 0 0 1 0
Titanimum 1 0 0 0
For this snapshot of table, I want to QUERY range to be {A:A\B:B\D:D}. However, as the data is computed, the table can be like this after 2hrs or the next day:
Items TypeA TypeB TypeC TypeD
Bronze 1 0 0 1
Silver 0 0 1 0
Gold 0 1 1 0
Titanimum 1 0 0 0
And so, for this snapshot of table, I want to QUERY range to be {A:A\B:B\C:C\D:D\E:E}.
Is this doable? And how can I achieve or construct a dynamic QUERY range?
Thanks for everyone...
You can remove columns from a range based on a criteria using the FILTER command.
Unfiltered
Items TypeA TypeB TypeC TypeD TypeE TypeF TypeG
Bronze 1 0 0 1 0 0 1
Silver 1 1 0 1 0 0 1
Gold 1 0 0 1 0 0 1
Titan 1 0 0 1 1 0 1
1 4 1 0 4 1 0 4
Filtered to remove columns with total of 0
Items TypeA TypeB TypeD TypeE TypeG
Bronze 1 0 1 0 1
Silver 1 1 1 0 1
Gold 1 0 1 0 1
Titan 1 0 1 1 1
The 'trick' is to sum the sum the column data (for your example) and then test for >0
The filter expression is:
=FILTER(A1:H5,A6:H6 >0)
By way of explanation:
A1:H5 is the range to be filtered;
A6:H6 >0 selects all columns that have a value > 0 in row 6
I placed a 1 in A6 to make sure colA is included.
You can now do queries on the range returned by the above expression.

How to apply function across each row and one of the parameters passed in is a table

I want to create a column that checks to see that each row of a table can be found in another table using 3 column ids. x, y and z are the columns of the table and transferrable is the second table
I tried this:
elligibleCrossMarginTransfers:{[x;y;z;transferrable]
potentialTransfers: select from transferrable where marginPctPost>collateralUpperLimitPct,not crossMargin;
if[1<count select from potentialTransfers where client=x, primeBroker=y,parentPortfolioId=z;
:1b]; //determine if parentPortfolio of crossMargin exists as possible transfer from other non-cross Margin counts
:0b
};
crossMarginNegExcess:update elligibleToTransfer:elligibleCrossMarginTransfers'[client;primeBroker;parentPortfolioId;transferrable] from crossMarginNegExcess
Are you looking for something like this?
q)0N!t:flip `a`b`c!(`a`b`c;1 2 3;10 20 30)
+`a`b`c!(`a`b`c;1 2 3;10 20 30)
a b c
------
a 1 10
b 2 20
c 3 30
q)0N!t2:flip `a`b`c!(`a`B`c;1 -2 3;10 -20 30)
+`a`b`c!(`a`B`c;1 -2 3;10 -20 30)
a b c
--------
a 1 10
B -2 -20
c 3 30
q)t[`elligibleToTransfer]:(`a`b#t) in `a`b#t2
q)t
a b c elligibleToTransfer
--------------------------
a 1 10 1
b 2 20 0
c 3 30 1
q)
updating with two examples you can attempt on your data (provide some samples for more complete answer)
crossMarginNegExcess[`elligibleToTransfer]:(`client`primeBroker`parentPortfolioId#crossMarginNegExcess) in select client,primeBroker,parentPortfolioId from transferrable where marginPctPost>collateralUpperLimitPct,not crossMargin
//all qsql
update elligibleToTransfer:1b from `crossMarginNegExcess where ([]client;primeBroker;parentPortfolioId) in select client,primeBroker,parentPortfolioId from transferrable where marginPctPost>collateralUpperLimitPct,not crossMargin

top n record of each group by active record rails

I have a table called result and it has source_id
id source_id text order
1 1 aaa 1
2 1 bbb 2
3 1 ccc 3
4 2 aaa 1
5 2 bbb 2
5 2 ccc 3
the question is how getting top 2 record order by order of each group by source_id? the result should be like this
source_id text order
1 aaa 1
1 bbb 2
2 aaa 1
2 bbb 2
I tried these queries and non of them are working
.group("source_id").order('order DESC').limit(30)
.group_by(&:source_id).map! { |source_id, latest_results_of_source| latest_results_of_source.limit(30)}
.group_by(&:source_id).map { |source_id, latest_results_of_source| latest_results_of_source.limit(30)}
.group_by(&:source_id).map { |source_id, latest_results_of_source| latest_results_of_source}
I would do something like this:
Result.find_by_sql("SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY source_id ORDER BY order DESC) AS r, results.* FROM results) x WHERE x.r <= 2 ORDER BY order")
You can try:
Result.where(order:[1,2]).order(:source_id, :order)

Resources