Convert rows in columns with informix query - sql

I want to convert
inpvacart inpvapvta inpvapvt1 inpvapvt2 inpvapvt3 inpvapvt4
CS-279 270.4149 0.0000 0.0000 0.0000 0.0000
AAA5030 1.9300 1.9300 1.6212 0.0000 0.0000
Query
select
inpvacart,
inpvapvta,
inpvapvt1,
inpvapvt2,
inpvapvt3,
inpvapvt4
from inpva;
into this
inpvacart line value
CS-279 1 270.4149
CS-279 2 0.00000
CS-279 3 0.00000
CS-279 4 0.00000
CS-279 5 0.00000
AAA5030 1 1.9300
AAA5030 2 1.9300
AAA5030 3 1.6212
AAA5030 4 0.0000
AAA5030 5 0.0000
I have tried this
select s.inpvacart,l.lista,l.resultados
from inpva as s,
table(values(1,s.inpvapvta),
(2,s.inpvapvt1),
(3,s.inpvapvt2),
(4,s.inpvapvt3),
(5,s.inpvapvt4))
)as l(lista,resultados);
But it does not work in informix 9
Is there a way to transpose rows to columns?
Thank You

I don't think Informix has any unpivot operator to transpose columns to rows like for instance MSSQL does, but one way to do this is to transpose the columns manually and then use union to create a single set like this:
select inpvacart, 1 as line, inpvapvta as value from inpva
union all
select inpvacart, 2 as line, inpvapvt1 as value from inpva
union all
select inpvacart, 3 as line, inpvapvt2 as value from inpva
union all
select inpvacart, 4 as line, inpvapvt3 as value from inpva
union all
select inpvacart, 5 as line, inpvapvt4 as value from inpva
order by inpvacart, line;
It's not very pretty but it should work.

Related

Select query when one column value is equal with column name

So I have this query where I need to select subtraction value of parent with busines of the codes.
For example let's say in the container table we have Parent value 0.39 and the child value 0.7 than the value fromthe selection would be -0.31‬.
Now this value (-0.31‬) I need to multiply it with the value of Quality column which is found in another table. Than I need the top 3 values. That means ordering by desc ofcourse.
But ofcourse it should be multiplied when NetNames is equal with BetNames and Codes column value is equal with one the columns in table container. (Q_1, Q_2, Q_3).
I'm lost here guys.
Below is info about my tables.
/*Table Container*/
BetNamesID | Parent_B_Id | Year | Month | Q_1 | Q_2 | Q_3
1 null 2020 5 0.36 0.3 0.21
6 2 2020 8 0.39 0.64 1.0
7 1 2020 9 0.76 0.65 0.29
8 3 2020 13 0.62 0.34 0.81
9 2 2020 2 0.28 0.8 1.0
/*Table Configuration*/
NetNames | Codes | Quality
Test 1 Q_1 5
Test 2 Q_5 7
Test 3 Q_2 24
Test 4 Q_3 98
Test 5 Q_4 22
/*Table BetNames Info*/
ID | Parent_B_Id | Name
1 null Test 1
6 2 Test 2
7 1 Test 3
8 3 Test 4
9 2 Test 5
What I have done until now is this query :
SELECT
child.[BetNamesID],
child.[Parent_B_Id],
child.[Q_1] - parent.[Q_1] AS Q_1,
child.[Q_2] - parent.[Q_2] AS Q_2,
child.[Q_3] - parent.[Q_3] AS Q_3,
// this is just a test case.. this is how it is supposed in my mind(child.[Q_3] - parent.[Q_3]) * qualityvalue AS Q_3, //this is how it is supposed to be
, n.name
FROM [dbo].[Container] child
join [dbo].[Container] parent on child.Parent_B_Id = parent.BetNamesID
join dbo.NetNames n on n.id = parent.Parent_B_Id //with this I get the names for BetNamesID
And this is the result of my query until now:
BetNamesID | Parent_B_Id | Q_1 | Q_2 | Q_3
3 2 0.21 -0.3 -0.1
5 4 -0.39 0.64 -0.9
8 5 0.99 0.65 0.59
What I need now is to multiply the values of Q_1, Q_2, Q_3 columns, with the values found in Config table (Quality column), only when BetNames is equal with NetNames and Codes row value is equal with Q_1 or Q_2 or Q_3 column.
These are the expected values.
BetNamesID | Parent_B_Id | Q_1 | Q_2 | Q_3
3 2 1.05‬(0.21 * 5) -7.2(-0.3* 24) -9.8 (-0.1* 98)
5 4 1.95(0.39*5) 15.36(0.64*24) -88.2 (-0.9*98)
How does the new Table come in play? How can I join? How does the where condition work in this case?

SUM in SQL Server with PARTITION BY clause

I have the following table
QuotationId QuotationDetailId DriverId RangeFrom RangeTo FixedAmount UnitAmount
-------------------------------------------------------------------------------------------
10579 7 1 1 1 1154.00 0.00
10579 7 2 2 2 1731.00 0.00
10579 11 1 0 10 0.00 88.53
10579 11 2 11 24 885.30 100.50
10579 11 3 25 34 2292.30 88.53
I need to write a query in SQL Server with the following logic,
The grouping is QuotationId + QuotationDetailId.
For each of this block I need to sum from the second line on the value of the previous line for fixed
Amount + UnitAmount * RangeFrom + FixedAmount of the current row
So in this case the resulting output should be
QuotationId QuotationDetailId DriverId RangeFrom RangeTo FixedAmount UnitAmount
10579 7 1 1 1 1154.00 0.00
10579 7 2 2 2 2885.00 0.00
10579 11 1 0 10 0.00 88.53
10579 11 2 11 24 1770.60 100.50
10579 11 3 25 34 7174.90 88.53
I've tried several queries but without success, can someone suggest me a way to do that ?
Best regards
Fabrizio
In SQL Server 2012+, you can do a cumulative sum. I'm not sure exactly what the logic is you want, but this seems reasonable given the data set:
select t.*,
sum(FixedAmount*UnitAmount) over (partition by QuotationId, QuotationDetailId
order by DriverId
) as running_sum
from t;
you can use a subquery, your 'amount' column would appear on the list of columns as a query in brackets,
SELECT ...fields...,
(SELECT SUM(A.unitAmount * A.RangeFrom + A.fixedAmount)
From YourTable A
WHERE A.QuotationId = B.QuotationId
AND A.QuotationDetailId = B.QuotationDetailId
AND A.DriverId <= B.DriverId) AS Amount
From YourTable B

group by in Matlab to find the value that resulted minimum similar to SQL

I have a dataset having columns a, b, c and d
I want to group the dataset by a,b and find c such that d is minimum for each group
I can do "group by" using 'grpstats" as :
grpstats(M,[M(:,1) M(:,2) ],{'min'});
I don't know how to find the value of M(:,3) that resulted the min in d
In SQL I suppose we use nested queries for that and use the primary keys. How can I solve it in Matlab?
Here is an example:
>> M =[4,1,7,0.3;
2,1,8,0.4;
2,1,9,0.2;
4,2,1,0.2;
2,2,2,0.6;
4,2,3,0.1;
4,3,5,0.8;
5,3,6,0.2;
4,3,4,0.5;]
>> grpstats(M,[M(:,1) M(:,2)],'min')
ans =
2.0000 1.0000 8.0000 0.2000
2.0000 2.0000 2.0000 0.6000
4.0000 1.0000 7.0000 0.3000
4.0000 2.0000 1.0000 0.1000
4.0000 3.0000 4.0000 0.5000
5.0000 3.0000 6.0000 0.2000
But M(1,3) and M(4,3) are wrong. The correct answer that I am looking for is:
2.0000 1.0000 9.0000 0.2000
2.0000 2.0000 2.0000 0.6000
4.0000 1.0000 7.0000 0.3000
4.0000 2.0000 3.0000 0.1000
4.0000 3.0000 4.0000 0.5000
5.0000 3.0000 6.0000 0.2000
To conclude, I don't want the minimum of third column; but I want it's values corresponding to minimum in 4th column
grpstats won't do this, and MATLAB doesn't make it as easy as you might hope.
Sometimes brute force is best, even if it doesn't feel like great MATLAB style:
[b,m,n]=unique(M(:,1:2),'rows');
for i =1:numel(m)
idx=find(n==i);
[~,subidx] = min(M(idx,4));
a(i,:) = M(idx(subidx),3:4);
end
>> [b,a]
ans =
2 1 9 0.2
2 2 2 0.6
4 1 7 0.3
4 2 3 0.1
4 3 4 0.5
5 3 6 0.2
I believe that
temp = grpstats(M(:, [1 2 4 3]),[M(:,1) M(:,2) ],{'min'});
result = temp(:, [1 2 4 3]);
would do what you require. If it doesn't, please explain in the comments and we can figure it out...
If I understand the documentation correctly, even
temp = grpstats(M(:, [1 2 4 3]), [1 2], {'min'});
result = temp(:, [1 2 4 3]);
should work (giving column numbers rather than full contents of columns)... Can't test right now, so can't vouch for that.

pandas: sort grouped dataframe by frequency of group members

I am interested in sorting a grouped dataframe by the number of entries for each group. As far as I can see, I can either sort by the group labels or not at all. Say I have 10 entries that belong to three groups. Group A has 6 members, group B has three members, and group C has 1 member. Now when I e.g. do a grouped.describe(), I would like the output to be ordered so that the group with the most entries is shown first.
I would unstack the statistics from describe(), then you can simply use sort(), so:
incsv = StringIO("""Group,Value
B,1
B,2
B,3
C,8
A,5
A,10
A,15
A,25
A,35
A,40""")
df = pd.read_csv(incsv)
groups = df.groupby('Group').describe().unstack()
Value
count mean std min 25% 50% 75% max
Group
A 6 21.666667 14.023789 5 11.25 20 32.5 40
B 3 2.000000 1.000000 1 1.50 2 2.5 3
C 1 8.000000 NaN 8 8.00 8 8.0 8
dfstats.xs('Value', axis=1).sort('count', ascending=True)
count mean std min 25% 50% 75% max
Group
C 1 8.000000 NaN 8 8.00 8 8.0 8
B 3 2.000000 1.000000 1 1.50 2 2.5 3
A 6 21.666667 14.023789 5 11.25 20 32.5 40
I reversed the sort just for illustration because it was already sorted by default, but you can sort anyway you want of course.
Bonus for anyone who can sort by count without dropping or stacking the 'Value' level. :)

SQL Query using Pivot

I have a table as follows:
PriorityText Priority LoRes Partial Unknown N_A HiRes
------------------------------------------------------------------
Very High 5 0.0612 0.0000 0.0612 0.0612 0.2041
High 4 0.1429 0.0000 0.1633 0.0000 0.1633
Medium 3 0.0000 0.0000 0.1020 0.0000 0.0408
Low-Medium 2 0.0000 0.0000 0.0000 0.0000 0.0000
Low 1 0.0000 0.0000 0.0000 0.0000 0.0000
I am tying to transpose the table into this:
PriorityText Low Low-Medium Medium High Very High
--------------------------------------------------------
Priority 1 2 3 4 5
LoRes 0 0 0 0.1429 0.0612
Partial 0 0 0 0 0
Unknown 0 0 0.102 0.1633 0.0612
N_A 0 0 0 0 0.0612
HiRes 0 0 0.0408 0.1633 0.2041
I am using SQL 2008. I am having trouble coming up with the SQL syntax to perform a pivot on the data.
Can someone please share a SQL snippet that will solve this for me?
I have used the following to successfully pivot one row, but I do not know how to make it do all my rows.
SELECT VeryHigh AS VeryHigh,
High AS High,
Medium AS Medium,
[Low-Medium] AS [Low-Medium],
Low AS Low
FROM (SELECT [PriorityText], [LoRes] FROM #tbTemp) p
PIVOT (SUM(LoRes) FOR [PriorityText] in ([VeryHigh], [High], [Medium], [Low-Medium], [Low])) pvt
My test data in my table is as follows:
Priority PriorityText LoRes Partial Unknown N_A HiRes
1 VeryHigh 0.05 11 54 0 9
2 High 0.14 22 54 0 3
3 Medium 0.07 33 65 0 7
4 Low-Medium 0.01 44 87 0 4
5 Low 0 55 9 0 0
NULL NULL NULL NULL NULL NULL NULL
Thank for any help!!
Not sure how hardcoded you can make this, but what your wanting to do is Transpose the Rows with the Columns.
SELECT p.[Type] as 'PriorityText', Low, [Low-Medium], Medium,High,[VeryHigh]
FROM (SELECT PriorityText, [Holder],[Type]
FROM (SELECT PriorityText,Priority,LoRes,[Partial],Unknown,N_A,HiRes
FROM Test) as sq_source
UNPIVOT ([Holder] FOR [Type] IN
(Priority,LoRes,[Partial],Unknown,N_A,HiRes)) as sq_up
) as sq
PIVOT (
MIN([Holder])
FOR PriorityText IN
(VeryHigh,High,Medium,[Low-Medium],Low)
) as p
order by CASE p.[Type] WHEN 'Priority' THEN 1
WHEN 'LoRes' THEN 2
WHEN 'Partial' THEN 3
WHEN 'Unknown' THEN 4
WHEN 'N_A' THEN 5
ELSE 6 END ASC;
This should get you what you need. One thing to note is this only works if the columns:
Priority
LoRes
Partial
Unknown
N_A
HiRes
are of the same data type (in my test it was decimal(5,4)). If yours are deferent then you will need to do an initial select and convert them to a common data type and use that as the sq_source.