Pivot on multiple fields and export from Access - sql

I have built an access application for a manufacturing plant and have provided them with a report that lists different data points along a process. I have a way to generate a report that looks like the following.
Batch Zone Value1 Value 2 etc.
25 1 5 15
25 2 12 31
26 1 6 14
26 2 10 32
However, there is demand to view the data in a different format. They would like one line per batch, with all data horizontal. Like this...
Zone 1 Zone 2
Batch Value1 Value2 Value1 Value2
25 5 15 12 31
26 6 14 10 32
In all there will be 157 columns, if displayed as in the second example. There are 7 unique field names, but the rest are 14 different data types that are repeated. I can't get a query to display the data in the format the they want, do to the fact that the field names are the same, but it is not hard to do it the first way. I can use VBA to insert the data into a table, but I can't use duplicate field names, so when I go to export this to Excel the field names won't mean anything, and there can't be sections (like zone1, zone2, etc.) I can link a report to this, but the report width can only be 22", so I would have to export and then do some vba handling of the excel sheet on the other end to display in a legible way.
I can get the data into format #1, is there some way I can get the data to display in one long row based on batch number? Does anyone else have a great idea of how this is doable?
Open to any suggestions. Thanks!

In your question you say that
I have a way to generate a report that looks like the following
and then list the data as
Batch Zone Value1 Value2
----- ---- ------ ------
25 1 5 15
25 2 12 31
26 1 6 14
26 2 10 32
Now perhaps the data may already be in "un-pivoted" form somewhere (with different Values in separate rows), but if not then you would use something like the following query to achieve that
SELECT
[Batch],
"Zone" & [Zone] & "_" & "Value1" AS [ValueID],
[Value1] AS [ValueValue]
FROM BatchDataByZone
UNION ALL
SELECT
[Batch],
"Zone" & [Zone] & "_" & "Value2" AS [ValueID],
[Value2] AS [ValueValue]
FROM BatchDataByZone
...returning:
Batch ValueID ValueValue
----- ------------ ----------
25 Zone1_Value1 5
25 Zone2_Value1 12
26 Zone1_Value1 6
26 Zone2_Value1 10
25 Zone1_Value2 15
25 Zone2_Value2 31
26 Zone1_Value2 14
26 Zone2_Value2 32
However you get to that point, if you save that query as [BatchDataUnpivoted] then you could use a simple Crosstab Query to "string out" the values for each batch...
TRANSFORM Sum(BatchDataUnpivoted.[ValueValue]) AS SumOfValueValue
SELECT BatchDataUnpivoted.[Batch]
FROM BatchDataUnpivoted
GROUP BY BatchDataUnpivoted.[Batch]
PIVOT BatchDataUnpivoted.[ValueID];
...returning...
Batch Zone1_Value1 Zone1_Value2 Zone2_Value1 Zone2_Value2
----- ------------ ------------ ------------ ------------
25 5 15 12 31
26 6 14 10 32

Related

SQL Query to find and remove characters

I am importing data from a flat file to a SQL table called TCVS_tmp_PO_Detail using SSIS and SQL. Now and then I get some characters in the Purchase Order column that I would like to find and eliminate if they occur.
The characters are , so could I trim these 3 characters on the left of the number out? It does not occur all the time so I can run it on the front end of my SSIS job as a query to correct it before exporting it.
Here is an example of what it looks like when it occurs
Purchase Order
7
7
8
8
8
8
8
8
9
10
10
10
10
11
12
13
11
12
13
14
14
15
15
16
16
17
19
18
19
20
22
I'm not sure where the data lies for the processing, but you can easily do this with a case expression:
(case when purchase_order like '%' then stuff(purchase_order, 1, 3, '')
else purchase_order
end) as purchase_order
I suppose you use "Data Flow Task"
Add "Derived Column" component
Add new column
Add this code to the Expression
REPLACE(Purchase,"","")
The results:

MS Access average a value based on other column data

So my data looks something like this:
Smpl_id Plate_id CT_Value
1 1 27
1 1 32
2 1 56
2 1 49
1 2 40
1 2 36
2 2 58
2 2 64
I would like to design a query that returns averages of CT_Value of each sample in a plate, so it would look like this:
Smpl_id Plate_id Avg_CT
1 1 29.5
2 1 52.5
1 2 38
2 2 61
I have tried
Avg_CT: DAvg("[CT_Value]","[qPCR_sample_data]","[Plate_id] = '" & [Plate_id] & "'" And "[Smpl_is] = '" & [Smpl_id] & "'")
But that just results in:
Smpl_id Plate_id CT_Value
1 1 45.25
1 1 45.25
2 1 45.25
2 1 45.25
1 2 45.25
1 2 45.25
2 2 45.25
2 2 45.25
I can't just list the plate or sample id numbers because this is actually a long list that is continually growing. I also need to use these average numbers in future calculations (that I have already figured out how to do).
Also, I have just started using MS Access (designing a brand new database), so I kinda understand SQL but have very little actual experience in it.
Thank you!
You will need to use a group by query.
Create a new query, and add the table (in my example I've called it tblSample).
Add the three fields, Smpl_id, Plate_id and CT_Value to the query grid.
On the Query Design memubar, click on the button labelled "Totals".
This introduces a new row in the query grid called "Total", with all three fields having it set to "Group By".
Simply change the "Group By" for CT_Value to "Avg", and run the query to get the results you are after:
Regards,
You should be able to use simple aggregation such as:
select t.smpl_id, t.plate_id, avg(t.ct_value) as avg_ct
from qpcr_sample_data t
group by t.smpl_id, t.plate_id

Percentage of variable corresponding to percentage of other variable

I have two numerical variables, and would like to calculate the percentage of one variable corresponding to at least 50% of the other variable's sum.
For example:
A | B
__________
2 | 8
1 | 20
3 | 12
5 | 4
2 | 7
1 | 11
4 | 5
Here, the sum of column B is 68, so I'm looking for the rows (in B's descending order) where cumulative sum is at least 34.
In that case, they are rows 2, 3 & 6 (cumulative sum of 45). The sum of these row's column A is 5, which I want to compare to the total sum of column A (18).
Therefore, the result I'm looking for is 5 / 18 * 100 = 28.78%
I'm looking for a way to implement this in QlikSense, or in SQL.
Here's one way you can do it - there is probably some optimisation to be done, but this gives what you want.
Source:
LOAD
*,
RowNo() as RowNo_Source
Inline [
A , B
2 , 8
1 , 20
3 , 12
5 , 4
2 , 7
1 , 11
4 , 5
];
SourceSorted:
NoConcatenate LOAD *,
RowNo() as RowNo_SourceSorted
Resident Source
Order by B asc;
drop table Source;
BTotal:
LOAD sum(B) as BTotal
Resident SourceSorted;
let BTotal=peek('BTotal',0);
SourceWithCumu:
NoConcatenate LOAD
*,
rangesum(peek('BCumu'),B) as BCumu,
$(BTotal) as BTotal,
rangesum(peek('BCumu'),B)/$(BTotal) as BCumuPct,
if(rangesum(peek('BCumu'),B)/$(BTotal)>=0.5,A,0) as AFiltered
Resident SourceSorted;
Drop Table SourceSorted;
I worked with a debug fields that might be useful but you could of course remove these.
Then in the front end you do your calculation of sum(AFiltered)/sum(A) to get the stat you want and format it as a percentage.

PowerPivot formula for row wise weighted average

I have a table in PowerPivot which contains the logged data of a traffic control camera mounted on a road. This table is filled the velocity and the number of vehicles that pass this camera during a specific time(e.g. 14:10 - 15:25). Now I want to know that how can I get the average velocity of cars for an specific hour and list them in a separate table with 24 rows(hour 0 - 23) where the second column of each row is the weighted average velocity of that hour? A sample of my stat_table data is given below:
count vel hour
----- --- ----
133 96.00237 15
117 91.45705 21
81 81.90521 6
2 84.29946 21
4 77.7841 18
1 140.8766 17
2 56.14951 14
6 71.72839 13
4 64.14309 9
1 60.949 17
1 77.00728 21
133 100.3956 6
109 100.8567 15
54 86.6369 9
1 83.96901 17
10 114.6556 21
6 85.39127 18
1 76.77993 15
3 113.3561 2
3 94.48055 2
In a separate PowerPivot table I have 24 rows and 2 columns but when I enter my formula, the whole rows get updated with the same number. My formula is:
=sumX(FILTER(stat_table, stat_table[hour]=[hour]), stat_table[count] * stat_table[vel])/sumX(FILTER(stat_table, stat_table[hour]=[hour]), stat_table[count])
Create a new calculated column named "WeightedVelocity" as follows
WeightedVelocity = [count]*[vel]
Create a measure "WeightedAverage" as follows
WeightedAverage = sum(stat_table[WeightedVelocity]) / sum(stat_table[count])
Use measure "WeightedAverage" in VALUES area of pivot Table and use "hour" column in ROWS to get desired result.

Sql Server Row Concatenation

I have a table (table variable in-fact) that holds several thousand (50k approx) rows of the form:
group (int) isok (bit) x y
20 0 1 1
20 1 2 1
20 1 3 1
20 0 1 2
20 0 2 1
21 1 1 1
21 0 2 1
21 1 3 1
21 0 1 2
21 1 2 2
And to pull this back to the client is a fairly hefty task (especially since isok is a bit). What I would like to do is transform this into the form:
group mask
20 01100
21 10101
And maybe go even a step further by encoding this into a long etc.
NOTE: The way in which the data is stored currently cannot be changed.
Is something like this possible in SQL Server 2005, and if possible even 2000 (quite important)?
EDIT: I forgot to make it clear that the original table is already in an implicit ordering that needs to be maintained, there isnt one column that acts as a linear sequence, but rather the ordering is based on two other columns (integers) as above (x & y)
You can treat the bit as a string ('0', '1') and deploy one of the many string aggregate concatenation methods described here: http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/