Transpose in Datatable in ASP.NET - asp.net

I have DataTable with two Column as "ID", "Value" with data as:
ID Value
A 100
A 200
A 300
A 400
A 500
B -100
B -99
B -98
B -97
C 1
C 2
C 3
C 4
I want to display this in GridView as:
A B C
100-100 1
200 -99 2
300 -98 3
400 -97 4
Which is the best way to Transpose this in DataTable. It would be really helpful if any one can provide an example.
Regards

I'm fairly familiar with OSI PI data and I've done the same after pulling PI tag data into an SQL Server database.
The trick is that there needs to be another column with the Start Time or End Time so the correct rows for A, B, and C can be matched up.
Then it's just a matter of using PIVOT (SQL Server 2005+ only) to group them:
SELECT *
FROM (SELECT ts_start, ID, Value FROM DataTable) v
PIVOT( SUM(Value) FOR ID IN ([A],[B],[C]) ) AS pvt
You can use just about any aggregate you want (MAX, MIN, SUM, etc.) above, it doesn't matter as long as there's only one value for each distinct combination of tag and timestamp. Aggregation is required by PIVOT, as are the aliases v and pvt (you can name them whatever you like).

Try this function (something i've recently had to do myself). The params are:
dtTableToTranspose = the table you want to transpose (obviously)
index = the column index that has the row key (in your case it will be 0)
private static DataTable TransposeADONETDataTable(DataTable dtTableToTranspose, Int32 index)
{
DataTable dtTransposedTable = new DataTable("TransposedTable");
String colName = dtTableToTranspose.Columns[index].ColumnName.ToString();
dtTransposedTable.Columns.Add(colName);
foreach (DataRow row in dtTableToTranspose.Rows)
{
dtTransposedTable.Columns.Add(row[index].ToString());
}
Int32 colIndex = 0;
foreach (DataColumn dc in dtTableToTranspose.Columns)
{
if (colIndex != index)
{
DataRow newRow = dtTransposedTable.NewRow();
newRow[0] = dc.ColumnName;
for (Int32 destColIndex = 1; destColIndex < dtTransposedTable.Columns.Count; destColIndex++)
{
newRow[destColIndex] = dtTableToTranspose.Rows[destColIndex - 1][colIndex];
}
dtTransposedTable.Rows.Add(newRow);
}
colIndex++;
}
return dtTransposedTable;
}

Related

Datatable second row to first row

In My Datatable iam getting 2 rows like
Name Age City
A 20 c
B 20 c
Now i need like second row shifted to First Row and vice versa
Name Age City
B 20 c
A 20 c
How can i do it.
If you want to swap two rows you can use following approach:
for (int i = 0; i < table.Rows.Count; i += 2)
{
object[] row1Items = table.Rows[i].ItemArray; // works because ItemArray creates a new object[]
table.Rows[i].ItemArray = table.Rows[i+1].ItemArray; // move second to first
table.Rows[i+1].ItemArray = row1Items; // move first to second
}
It even works with more than two, it swaps every consecutive pair of rows.
It seems like you want to sort rows in your DataTable by Name.
To achieve this, you can use the following example :
Dim dv As DataView = dt.DefaultView
dv.Sort = "Name desc" ' Where "Name" is your column name
dt = dv.ToTable()

Sqlite3 column division

I have the following columns (FirstCol, SecondCol, ThirdCol) in a sqlite3 db file:
1 Inside 100
1 Outside 200
2 Inside 46
2 Outside 68
First column has type INT, second has type TEXT and third one has type INT.
For each FirstCol value (in this case just 1 and 2) i need to obtain the result of the value associated with Outside/Inside, which is to say 200/100 where FirstCol=1 and 68/46 where FirstCol=2.
I don't mind whether this is done with a single query or by creating a new table, i just need that result.
Thanks.
You have to look up the values from different rows with correlated subqueries:
SELECT FirstCol,
(SELECT ThirdCol
FROM MyTable
WHERE FirstCol = T.FirstCol
AND SecondCol = 'Outside'
) /
(SELECT ThirdCol
FROM MyTable
WHERE FirstCol = T.FirstCol
AND SecondCol = 'Inside'
) AS Result
FROM (SELECT DISTINCT FirstCol
FROM MyTable) AS T;

count the unique values in one column in EXCEL 2010 or R with 1 million rows

After searching the forum, I did not find a good solution for this question. If I missed it, please tell me.
I need to count the unique values in one column in EXCEL 2010.
The worksheet has 1 million rows and 10 columns. All cell values are string or numbers.
I used the solution at Count unique values in a column in Excel
=SUMPRODUCT((A2:A1000000<>"")/COUNTIF(A2:A100000,A2:A1000000&""))
But, it runs so long time that the EXCEL is almost frozen. And, it generates 25 processes in Win 7.
Are there more efficient ways to do it?
Also, in the column, all values have for format of
AX_Y
here, A is a character, X is an integer, Y is an integer from 1 to 10.
For example, A5389579_10
I need to cut off the part after (including) undersocre. for the example,
A5389579
This is what I need to count as unique values in all cells in one column.
For example, A5389579_10
A1543848_6
A5389579_8
Here, the unique value has 2 after removing the part after underscore.
How to do it in EXCEL VBA and R (if no efficient solution for EXCEL)?
If you want to do this by VBA, you can take advantage of the Collection object. Since collections can only contain unique values, trying to add all of your input data to a collection will result in an array of unique values. The code below takes all the variables in a selected range and then outputs an array with distinct values to an other sheet (in this case a sheet named Output).
Sub ReturnDistinct()
Dim Cell As Range
Dim i As Integer
Dim DistCol As New Collection
Dim DistArr()
Dim OutSht As Worksheet
Dim LookupVal As String
Set OutSht = ActiveWorkbook.Sheets("Output") '<~~ Define sheet to putput array
If TypeName(Selection) <> "Range" Then Exit Sub
'Add all distinct values to collection
For Each Cell In Selection
If InStr(Cell.Value, "_") > 0 Then
LookupVal = Mid(Cell.Value, 1, InStr(Cell.Value, "_") - 1)
Else
LookupVal = Cell.Value
End If
On Error Resume Next
DistCol.Add LookupVal, CStr(LookupVal)
On Error GoTo 0
Next Cell
'Write collection to array
ReDim DistArr(1 To DistCol.Count, 1 To 1)
For i = 1 To DistCol.Count Step 1
DistArr(i, 1) = DistCol.Item(i)
Next i
'Outputs distinct values
OutSht.Range("A1:A" & UBound(DistArr)).Value = DistArr
End Sub
Note that since this code writes all the distinct values to a single column in the OutSht-sheet, this will return an error if there are more than 1,048,576 distinct values in your dataset. In that case you would have to split the data to be filled into multiple output columns.
For your specific request to count, use the below in a formula like =COUNTA(GetUniques(LEFT("A1:A100000",FIND("_","A1:A100000")-1)) entered as an array formula with Ctrl+Shift+Enter.
It also accepts multiple ranges / values (e.g. GetUniques("A1:A10","B2:E4"))
Function GetUniques(ParamArray args())
Dim arg, ele, arr, i As Long
Dim c As Collection
Set c = New Collection
For Each arg In args
If TypeOf arg Is Range Then
If arg.Count = 1 Then
arr = array(arg.value)
Else
arr = arg.Value
End If
ElseIf VarType(arg) > vbArray Then
arr = arg
Else
arr = Array(arg)
End If
For Each ele In arr
On Error Resume Next
c.Add ele, VarType(ele) & "|" & CStr(ele)
On Error GoTo 0
Next ele
Next arg
If c.Count > 0 Then
ReDim arr(0 To c.Count - 1)
For i = 0 To UBound(arr)
arr(i) = c(i + 1)
Next i
Set c = Nothing
GetUniques = arr
End If
End Function
edit: added a performance optimisation for ranges (loads them at once into an array - much faster than enumerating through a range)
In R:
# sample data
df <- data.frame(x=1:1000000,
y=sample(1e6:(1e7-1),1e6,replace=T))
df$y <- paste0("A",df$y,"_",sample(1:10,1e6,replace=T))
# this does the work...
length(unique(sub("_[0-9]+","",df$y)))
# [1] 946442
# and it's fast...
system.time(length(unique(sub("_[0-9]+","",df$y))))
# user system elapsed
# 2.01 0.00 2.02
In excel 2010... in the next column add (if original data was in A:A add in B1)
= 1/COUNTIF(A:A,A1) and copy down col B to the bottom of your data. Depending on your PC it may chug away calculating for a long time, but it will work. Then copy col B & paste values over itself.
Then SUM col B

Unable to disting the record in Link Expression

I have two tables: TblAppointmentTypes and TblEmployeeInfo. There is many to many relation between these two tables with a joined table that is TblEmployeeServices. There are two records in TblAppointmentTypes and four records in TblEmployeeInfo. All the two records of TblAppointmentTypes is assigned to all of the records in TblEmployeeInfo, that there is eight records in TblEmployeeServices. I want to retrive all the services that are assigned to all the four Employees, it should return 2 that is assigned to all the four employees, but my query return 8 records, four duplicate services.
I am using Telerik Open Access ORM. Here is the code:
public static List<TblAppointmentType> GetAllAppointmentType(List<int> employeeIDs)
{
var list = new List<TblAppointmentType>();
if (employeeIDs != null && employeeIDs.Count > 0)
{
var dc = new Entities();
list = (from a in dc.TblAppointmentTypes.Distinct()
join e in dc.TblEmployeeServices on a.ID equals e.AppointmentTypeID
where a.IsDeleted == false && employeeIDs.Contains<int>(e.EmployeeID)
select a).ToList();
}
return list;
}
As I figured it out, You want to get all AppointmentTypes which are related to all Employees.
It means that AppTypes that are related to 3 Employees (in your case) should be excluded.
So, the most efficient code that I have tried is like this :
list = (from a in dc.TblAppointmentTypes
join e in dc.TblEmployeeServices on a.ID equals e.AppointmentTypeID
where a.IsDeleted == false
group e.EmployeeID by a into g
where g.count() == employeeIDs.Count()
select g.Key).ToList();

Datatable's Compute Function For Rows

As we know that, with compute function of datatable we can get sum of columns.
But I want to get sum of a row of datatable.
I will explain with a example:
I have a datatable like image below: With compute function we can get the sum of each column (product). Such as for product1, 2 + 12 + 50 + 13= 77.
I want to get sum of company1 : 2 + 6 + 4 + 3 + 5 = 20
http://img123.imageshack.us/img123/1517/61519307xx5.jpg
How can I do it with asp.net 1.1?
LINQ to the rescue:
DataTable dt = WhateverCreatesDataTable();
DataRow dr = dt.Rows[0];
int sum = dt.Columns.Cast<DataColumn>().Sum(dc=>(int)dr[dc]);
For those still dragging their knuckles in the stone ages (aka pre-.Net 3.5 and LINQ):
DataTable dt = WhateverCreatesDataTable();
DataRow dr = dt.Rows[0];
int sum = 0;
foreach(DataColumn dc in dt.Columns)
sum += (int)dr[dc];
From msdn:
If you must perform an operation on
two or more columns, you should create
a DataColumn, set its Expression
property to an appropriate expression,
and use an aggregate expression on the
resulting column. In that case, given
a DataColumn with the name "total",
and the Expression property set to
this:
"Quantity * UnitPrice"
Since you want to solve this in 1.1 here is what you can do as a simple solution
DataColumn totalColumn = new DataColumn();
totalColumn.DataType = System.Type.GetType("System.Int32");
totalColumn.ColumnName = "Total";
totalColumn.Expression = "Product1 + Product2 + Product3 + Product4 + Product5";
// Populate and get the DataTable dt then add this computed column to this table
dt.Columns.Add(totalColumn);
//Now if you access the column "Total" of the table you will get the desired result.
We can use Datatable's Compute() function for the following purpose:
To find sum.
To find max value.
To find min value.
To calculate average.
Below links have detailed explaination of Datatable's compute() function:
http://codevariation.blogspot.com/2017/02/using-datatable-compute-function-in-cnet.html
Hope this will help you.
Thanks.

Resources