I am trying to create a dashboard query that can join 2 tables based on port and carrier. The issue I have is that I need to select the value from Carrier1, or 2, or 3, or 4 based on the value of DVB-S2X Uplink Port. (See figure).
Is there a way to write such a query that selects value from 4 columns based on value from Port?
Hi Anna,
Joining tables always happens on a fixed column, so you'll need to create a column that always contains the value you want to join on.
If like Sebastian suggests only 1 of the Carrier columns is filled in for each row, you can use the Column Manipulations > Concatenate operation. Then select your 4 Carrier columns and use format {0}{1}{2}{3} to get the new value to join on.
If multiple Carrier columns in a row can have a value, you can write a custom operator to add a new column and fill it in with the correct Carrier value based on the Uplink Port column. This tutorial shows the basics of creating a custom operator: DataMiner Docs Custom Operator Tutorial
The code for this custom operator could look something like this:
(Note this is untested code)
[GQIMetaData(Name = "Select carrier")] public class SelectCarrierOperator : IGQIColumnOperator, IGQIRowOperator, IGQIInputArguments
{
// Define input arguments
private readonly GQIColumnDropdownArgument _portColumnArgument = new GQIColumnDropdownArgument("Port column")
{
Types = new[] { GQIColumnType.String },
};private readonly GQIColumnListArgument _carrierColumnsArgument = new GQIColumnListArgument("Carrier columns")
{
Types = new[] { GQIColumnType.String },
};// Define output column
private readonly GQIStringColumn _selectedCarrierColumn = new GQIStringColumn("Selected carrier");// Variables to store the input argument values
private GQIColumn<string> _portColumn;
private GQIColumn<string>[] _carrierColumns;// Provide the arguments
public GQIArgument[] GetInputArguments() => new GQIArgument[] { _portColumnArgument, _carrierColumnsArgument };// Retrieve the argument values
public OnArgumentsProcessedOutputArgs OnArgumentsProcessed(OnArgumentsProcessedInputArgs args)
{
_portColumn = (GQIColumn<string>)args.GetArgumentValue(_portColumnArgument);
_carrierColumns = args.GetArgumentValue(_carrierColumnsArgument)
.Cast<GQIColumn<string>>()
.ToArray();// Do some validation of the argument values
if (_carrierColumns.Length != 4)
throw new GenIfException("Expected exactly 4 carrier columns.");return default;
}// Add the output column
public void HandleColumns(GQIEditableHeader header) => header.AddColumns(_selectedCarrierColumn);public void HandleRow(GQIEditableRow row)
{
// Determine carrier column to use based on the port column
var port = row.GetValue(_portColumn);
var carrierColumn = GetCarrierColumn(port);// Copy the carrier value to use to the output column
var carrier = row.GetValue(carrierColumn);
row.SetValue(_selectedCarrierColumn, carrier);
}private GQIColumn<string> GetCarrierColumn(string port)
{
switch (port)
{
case "1": return _carrierColumns[0];
case "2": return _carrierColumns[1];
case "3": return _carrierColumns[2];
default: return _carrierColumns[3];
}
}
}
Hi Anna,
Are the Carrier 1, 2, 3 and 4 columns always filled in? Or depending on the port, only one of those will be filled in?
If it is the case that only one carrier will get filled in, perhaps you can use column manipulations to concatenate carrier 1, 2, 3 and 4, and produce a new column that contains the value of the carrier that is populated.