DAX in calculated column - dax

I have two tables as below.
Table1
CaseId
66787
Table2
PrimaryKey CaseId SeqNo Status Primary Code CodeCareNo
85248 66787 6 Active N 876 8775568
70728 66787 1 Inactive N 876 3661794
79008 66787 5 Active Y 876 3766066
86868 66787 7 Active Y 876 3287735
Table 1 has one to many relationships with Table2 and the relating column in CaseId.
I have a requirement to create a calculated column in Table1 in my model project. The calculated column should display a text like (Code) CodeCareNo (eg: (876) 3766066) for each CaseId in Table1 with the values from Code and CodeCareNo columns of Table2 which has Primary = “Y” and Status = “Active” with Seq No as the minimum value among the primary active code numbers for the CaseId. Also if the Code or CodeCareNo is null the calculated column should show blank value. I am able to get the desired result with below query but I feel it bit messy. Can someone help me in simplifying the same?
=IF("(" & LOOKUPVALUE(Table2[Code], Table2[CaseId], Table1[CaseId],
Table2[Primary], "Y", Table2[Status], "Active", Table2[SeqNo],
MINX(FILTER(Table2, ( Table2[Primary] = "Y" && Table2[Status] = "Active" &&
Table2[CaseId] = Table1[CaseId])), Table2[SeqNo])) & ") " &
LOOKUPVALUE(Table2[CodeCareNo], Table2[CaseId], Table1[CaseId],
Table2[Primary], "Y", Table2[Status], "Active", Table2[SeqNo],
MINX(FILTER(Table2, ( Table2[Primary] = "Y" && Table2[Status] = "Active" &&
Table2[CaseId] = Table1[CaseId])), Table2[SeqNo])) = "() ", BLANK(), "(" &
LOOKUPVALUE(Table2[Code], Table2[CaseId], Table1[CaseId], Table2[Primary],
"Y", Table2[Status], "Active", Table2[SeqNo], MINX(FILTER(Table2, (
Table2[Primary] = "Y" && Table2[Status] = "Active" && Table2[CaseId] =
Table1[CaseId])), Table2[SeqNo])) & ") " & LOOKUPVALUE(Table2[CodeCareNo],
Table2[CaseId], Table1[CaseId], Table2[Primary], "Y", Table2[Status],
"Active", Table2[SeqNo], MINX(FILTER(Table2, ( Table2[Primary] = "Y" &&
Table2[Status] = "Active" && Table2[CaseId] = Table1[CaseId])),
Table2[SeqNo])) )

That's quite the mess. Try this formulation:
CodeCase =
VAR SeqNo = CALCULATE(MIN(Table2[SeqNo]), Table2[Primary] = "Y", Table2[Status] = "Active")
VAR Code = LOOKUPVALUE(Table2[Code], Table2[SeqNo], SeqNo)
VAR CodeCareNo = LOOKUPVALUE(Table2[CodeCareNo], Table2[SeqNo], SeqNo)
RETURN IF(ISBLANK(Code) || ISBLANK(CodeCareNo), BLANK(), "(" & Code & ") " & CodeCareNo)
(I like to use variables for computational efficiency and readability.)

Related

discord.py sqlite3.OperationalError: no such column:

...
winner_of_lottery = bot.get_user(person_id)
money = 100 * len(list_of_participants)
if winner_of_lottery and id != 9090:
base.execute("UPDATE users SET balance = balance + {} WHERE id = {}".format(money, winner))
base.execute("""UPDATE general SET last_winner = {} WHERE num = 1""".format(winner_of_lottery.name))
base.execute("""UPDATE general SET last_winner_sum = {} WHERE num = 1""".format(money))
Error
sqlite3.OperationalError: no such column:
in line
base.execute("""UPDATE general SET last_winner = {} WHERE num = 1""".format(winner_of_lottery.name))
sql table:
cursor.execute("""CREATE TABLE IF NOT EXISTS general (
last_winner TEXT,
last_winner_sum INT,
num INT
)""")
I don't know what am I need to do. Please, help
I try clear this problem since yesterday.
P.S. table is not empty
if cursor.execute("""SELECT last_winner FROM general WHERE num = 1""").fetchone() is None:
cursor.execute("""INSERT INTO general VALUES ("аноним:alien:", 200, 1)""")
base.commit()

GORM hangs with parameter

The below queries hangs exactly after 5 calls every time,
tx := db.Raw("select count(*) as hash from transaction_logs left join blocks on transaction_logs.block_number = blocks.number"+
" where (transaction_logs.address = ? and transaction_logs.topic0 = ?) and blocks.total_confirmations >= 7 "+
"group by transaction_hash", strings.ToLower("0xa11265a58d9f5a2991fe8476a9afea07031ac5bf"),
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef").Scan(&totalIds)
If we replace it without the arguments it works
db.Raw("select count(*) as hash from transaction_logs left join blocks on transaction_logs.block_number = blocks.number"+
" where (transaction_logs.address = #tokenAddress and transaction_logs.topic0 = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef') and blocks.total_confirmations >= 7 "+
"group by transaction_hash", sql.Named("tokenAddress", strings.ToLower("0xa11265a58d9f5a2991fe8476a9afea07031ac5bf"))
Tried even with named parameter, same result
Can anyone help here

LINQ - Previous Record

All:
Lets say I have the following table:
RevisionID, Project_ID, Count, Changed_Date
1 2 4 01/01/2016: 01:02:01
2 2 7 01/01/2016: 01:03:01
3 2 8 01/01/2016: 01:04:01
4 2 3 01/01/2016: 01:05:01
5 2 15 01/01/2016: 01:06:01
I am ordering the records based on Updated_Date. A user comes into my site and edits record (RevisionID = 3). For various reasons, using LINQ (with entity framework), I need to get the previous record in the table, which would be RevisionID = 2 so I can perform calculations on "Count". If user went to edit record (RevisionID = 4), I would need to select RevisionID = 3.
I currently have the following:
var x = _db.RevisionHistory
.Where(t => t.Project_ID == input.Project_ID)
.OrderBy(t => t.Changed_Date);
This works in finding the records based on the Project_ID, but how then do I select the record before?
I am trying to do the following, but in one LINQ statement, if possible.
var itemList = from t in _db.RevisionHistory
where t.Project_ID == input.Project_ID
orderby t.Changed_Date
select t;
int h = 0;
foreach (var entry in itemList)
{
if (entry.Revision_ID == input.Revision_ID)
{
break;
}
h = entry.Revision_ID;
}
var previousEntry = _db.RevisionHistory.Find(h);
Here is the correct single query equivalent of your code:
var previousEntry = (
from r1 in db.RevisionHistory
where r1.Project_ID == input.Project_ID && r1.Revision_ID == input.Revision_ID
from r2 in db.RevisionHistory
where r2.Project_ID == r1.Project_ID && r2.Changed_Date < r1.Changed_Date
orderby r2.Changed_Date descending
select r2
).FirstOrDefault();
which generates the following SQL query:
SELECT TOP (1)
[Project1].[Revision_ID] AS [Revision_ID],
[Project1].[Project_ID] AS [Project_ID],
[Project1].[Count] AS [Count],
[Project1].[Changed_Date] AS [Changed_Date]
FROM ( SELECT
[Extent2].[Revision_ID] AS [Revision_ID],
[Extent2].[Project_ID] AS [Project_ID],
[Extent2].[Count] AS [Count],
[Extent2].[Changed_Date] AS [Changed_Date]
FROM [dbo].[RevisionHistories] AS [Extent1]
INNER JOIN [dbo].[RevisionHistories] AS [Extent2] ON [Extent2].[Project_ID] = [Extent1].[Project_ID]
WHERE ([Extent1].[Project_ID] = #p__linq__0) AND ([Extent1].[Revision_ID] = #p__linq__1) AND ([Extent2].[Changed_Date] < [Extent1].[Changed_Date])
) AS [Project1]
ORDER BY [Project1].[Changed_Date] DESC
hope I understood what you want.
Try:
var x = _db.RevisionHistory
.FirstOrDefault(t => t.Project_ID == input.Project_ID && t.Revision_ID == input.Revision_ID -1)
Or, based on what you wrote, but edited:
_db.RevisionHistory
.Where(t => t.Project_ID == input.Project_ID)
.OrderBy(t => t.Changed_Date)
.TakeWhile(t => t.Revision_ID != input.Revision_ID)
.Last()

LINQ and 2 datatables

I have 2 datatables in a dataset. One table has a list called CostTypes. Just an Id and Description field.
The other datatable is the master table and has many records and one of the columns is the cost type. There will be cost types that are not reference in this datatable. There is another column in this databale called cost.
What I am trying to do is get a summary by cost type with a total of the cost. But I want ALL cost types listed any values not in the master table will be zero.
CostType table
Id, Description
1,Marketing
2,Sales
3,Production
4,Service
Master table
Id, Cost, CostTypeId
1,10,1
2,120,1
3,40,3
So I would like to see a result in a datable (if possible) so I can bind to datagridview
Marketing 130
Sales 0
Production 40
Service 0
Thanks for the help everyone, this is what I came up from the answers - Can anyone suggest any improvements???
Also how can I convert the result in query1 into a datable???
var query1 =
from rowCT in costTypes.AsEnumerable()
from rowSTD in stdRates.AsEnumerable()
.Where( d => d.Field<int?>( "CostTypeId" ) == rowCT.Field<int?>( "CostTypeId" ) )
.DefaultIfEmpty()
group new { row0 = rowCT, row1 = rowSTD }
by rowCT.Field<string>( "Description" ) into g
select new
{
g.Key,
Cost = g.Sum( x => x.row1 == null ? 0 : x.row1.Field<decimal>( "Cost" ) ),
TotalCost = g.Sum( x => x.row1 == null ? 0 : x.row1.Field<decimal>( "TotalCost" ) ),
TotalHours = g.Sum( x => x.row1 == null ? 0 : x.row1.Field<decimal>( "TotalHours" ) ),
TotalLabourCost = g.Sum( x => x.row1 == null ? 0 : x.row1.Field<decimal>( "TotalLabourCost" ) )
}
;
Maybe something like this:
Test data:
DataTable dt=new DataTable();
dt.Columns.Add("Id",typeof(int));
dt.Columns.Add("Description",typeof(string));
dt.Rows.Add(1,"Marketing");
dt.Rows.Add(2,"Sales");
dt.Rows.Add(3,"Production");
dt.Rows.Add(4,"Service");
DataTable dt2=new DataTable();
dt2.Columns.Add("Id",typeof(int));
dt2.Columns.Add("Cost",typeof(int));
dt2.Columns.Add("CostTypeId",typeof(int));
dt2.Rows.Add(1,10,1);
dt2.Rows.Add(2,120,1);
dt2.Rows.Add(3,40,1);
Linq query
var query=(
from row in dt.AsEnumerable()
from row1 in dt2.AsEnumerable()
.Where (d =>d.Field<int>("Id")==row.Field<int>("Id") )
.DefaultIfEmpty()
group new{row,row1}
by row.Field<string>("Description") into g
select new
{
g.Key,
Cost=g.Sum (x =>x.row1==null?0:x.row1.Field<int>("Cost"))
}
);
Result
Key Cost
Marketing 10
Sales 120
Production 40
Service 0
You can use the Sum extension method to compute the cost. It will return 0 if the collection is empty which is exactly what you want:
var costTypes = new DataTable("CostTypes");
costTypes.Columns.Add("Id", typeof(Int32));
costTypes.Columns.Add("Description", typeof(String));
costTypes.Rows.Add(1, "Marketing");
costTypes.Rows.Add(2, "Sales");
costTypes.Rows.Add(3, "Production");
costTypes.Rows.Add(4, "Service");
var costEntries = new DataTable("CostEntries");
costEntries.Columns.Add("Id", typeof(Int32));
costEntries.Columns.Add("Cost", typeof(Int32));
costEntries.Columns.Add("CostTypeId", typeof(Int32));
costEntries.Rows.Add(1, 10, 1);
costEntries.Rows.Add(2, 120, 1);
costEntries.Rows.Add(3, 40, 3);
var costs = costTypes
.Rows
.Cast<DataRow>()
.Select(
dr => new {
Id = dr.Field<Int32>("Id"),
Description = dr.Field<String>("Description")
}
)
.Select(
ct => new {
ct.Description,
TotalCost = costEntries
.Rows
.Cast<DataRow>()
.Where(ce => ce.Field<Int32>("CostTypeId") == ct.Id)
.Sum(ce => ce.Field<Int32>("Cost"))
}
);
The result is:
Description|TotalCost
-----------+---------
Marketing | 130
Sales | 0
Production | 40
Service | 0
You can create a new DataSet quite simply:
var costsDataTable = new DataTable("Costs");
costsDataTable.Columns.Add("Description", typeof(String));
costsDataTable.Columns.Add("TotalCost", typeof(Int32));
foreach (var cost in costs)
costsDataTable.Rows.Add(cost.Description, cost.TotalCost);
If the linear search performed by the Where in the code above is a concern you can improve the performance by creating a lookup table in advance:
var costEntriesLookup = costEntries
.Rows
.Cast<DataRow>()
.Select(
ce => new {
Cost = ce.Field<Int32>("Cost"),
CostTypeId = ce.Field<Int32>("CostTypeId")
}
)
.ToLookup(ce => ce.CostTypeId, ce => ce.Cost);
var costs = costTypes
.Rows
.Cast<DataRow>()
.Select(
dr => new {
Id = dr.Field<Int32>("Id"),
Description = dr.Field<String>("Description")
}
)
.Select(
ct => new {
ct.Description,
TotalCost = costEntriesLookup.Contains(ct.Id)
? costEntriesLookup[ct.Id].Sum()
: 0
}
);
I came up with a simpler bit of linq than others seemed to use. Thanks to Martin Liversage for the code to create the input data.
var costTypes = new DataTable("CostTypes");
costTypes.Columns.Add("Id", typeof(Int32));
costTypes.Columns.Add("Description", typeof(String));
costTypes.Rows.Add(1, "Marketing");
costTypes.Rows.Add(2, "Sales");
costTypes.Rows.Add(3, "Production");
costTypes.Rows.Add(4, "Service");
var costEntries = new DataTable("CostEntries");
costEntries.Columns.Add("Id", typeof(Int32));
costEntries.Columns.Add("Cost", typeof(Int32));
costEntries.Columns.Add("CostTypeId", typeof(Int32));
costEntries.Rows.Add(1, 10, 1);
costEntries.Rows.Add(2, 120, 1);
costEntries.Rows.Add(3, 40, 3);
var cte = costTypes.Rows.Cast<DataRow>();
var cee = costEntries.Rows.Cast<DataRow>();
var output = cte.Select(
ct => new {
Description = ct["Description"],
Sum = cee.Where(ce=>ce["CostTypeId"].Equals(ct["Id"])).Sum(ce=>(int)ce["Cost"])
}
);
This may lose efficiency on larger tables since each cost type will search the cost entry table whereas using grouping I suspect you only need one pass over the table. Personally I'd prefer the (to my mind) simpler looking code. It will depend on your use case though.

Inner join the same column of a table to multiple tables

I have a main table Fruit, and I'd like to join it to tables ApplePrice, PearPrice, and BananaPrice.
Fruit
Id Type Date
--------------------
1 Apple 1/1
2 Apple 1/3
3 Banana 1/5
4 Pear 1/7
Common Denominator of [Apple/Pear/Banana]Price (there are many more specific fields for each table):
Date Price F1 F2 ...
-----------------------
1/1 p1
1/2 p2
....
To get the price of each piece of Fruit, I join the Fruit table with each price table separately, then concatenate the results together.
If the Price tables can't be merged into one, do you have a better approach to this problem? For example, construct one Linq query that returns all the information instead of concatenating results from multiple queries.
Appreciate your ideas.
You need to use join into then DefaultIfEmpty. The LINQ equivalent of a SQL LEFT JOIN.
from fruit in fruits
join ap in applePrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Apple" + ap.Date.ToShortDateString())
into aps
from applePrice in aps.DefaultIfEmpty()
This will give:
Fruit | Apple Price | Banana Price | Pear Price
--------+-------------+--------------+------------
Apple | applePrice | null | null
Apple | applePrice | null | null
Banana | null | bananaPrice | null
Pear | null | null | pearPrice
Then select the valid fruitPrice values by the below:
applePrice != null
? applePrice.Price
: bananaPrice != null
? bananaPrice.Price
: pearPrice != null
? pearPrice.Price
: 0 // Default value here if all 3 are null
And use LINQ to select the wanted fields.
The complete result below, I've used an anonymous class to hold my values:
var prices = from fruit in fruits
join ap in applePrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Apple" + ap.Date.ToShortDateString())
into aps
from applePrice in aps.DefaultIfEmpty()
join bp in bananaPrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Banana" + bp.Date.ToShortDateString())
into bps
from bananaPrice in bps.DefaultIfEmpty()
join pp in pearPrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Pear" + pp.Date.ToShortDateString())
into pps
from pearPrice in pps.DefaultIfEmpty()
select new
{
Id = fruit.Id,
Type = fruit.Type,
Date = fruit.Date,
Price =
applePrice != null
? applePrice.Price
: bananaPrice != null
? bananaPrice.Price
: pearPrice != null
? pearPrice.Price
: 0
};
var prices = from T in bank.students
join O in bank.dovres
on (T.code) equals
(O.codestu)
into aps
from applePrice in aps.DefaultIfEmpty()
join Y in bank.rotbes
on (T.code) equals (Y.codestu)
into bps
from bananaPrice in bps.DefaultIfEmpty()
select new
{
Id = T.code,
Type =T.name,
Date = T.family,
father=T.fathername,
T.adi_date, T.faal_date,
// = applePrice.sal + " ماه و " + O.mah + " روز", hk = Y.sal + " ماه و " + Y.mah + " روز"
hj = applePrice != null
? applePrice.sal + " ماه و " + applePrice.mah + " روز"
:"",
hj1 = bananaPrice!= null
? bananaPrice.sal + " ماه و " +bananaPrice.mah + " روز"
: "",
};
dataGridView1.DataSource = prices;
dataGridView1.Columns[0].HeaderText = "کد ";
dataGridView1.Columns[1].HeaderText = "نام";
dataGridView1.Columns[2].HeaderText = "نام خانوادگی";
dataGridView1.Columns[3].HeaderText = "نام پدر";
dataGridView1.Columns[4].HeaderText = " عضویت عادی";
dataGridView1.Columns[5].HeaderText = "عضویت فعال";
dataGridView1.Columns[6].HeaderText = "کسری بسیج";
dataGridView1.Columns[7].HeaderText = "کسری جبهه";
This is the best code for joining 3 or more tables.

Resources