Table Manipulation in DB2 - sql

I am using DB2 and have the following table (Table A - 3 Columns) :
EmpNum YearMonth Value
100 201201 2
100 201207 1
100 201206 7
102 201201 8
102 201205 15
102 201207 4
… etc
I would like to produce a new Table B with one row per employee, and a column for each YearMonth.
I am hoping that I can generate the Table B 'YearMonth' column name dynamically from the data as there will be 120 columns.
The value would then be put in the cell with the associated YearMonth heading to give a table like this :
EmpNum 201201 201202 201203 201204 201205 201206 201207 etc ….
100 2 7 1
102 8 15 4
I have tried looking up 'Stored Procedures' and 'Dynamic Column Names' but cannot fine anything quite like this.
I have two questions :
Is this possible in DB2 ?
What should I look up for more information ?
Thanks in anticipation !
Ross

What you are looking for is called Pivot. Unfortunately, DB2 doesn't implement the PIVOT statement (unlike Oracle). So it will not be possible to create a query that creates a dynamic number of columns.
Have a look at Poor Man's SQL Pivot. List Questions as Columns and Answers per User in one row. That's the closest you can get to.

This is a generic procedure that allows to pivot a table: https://github.com/angoca/db2tools/blob/master/pivot.sql

Related

add column with fixed values for each value of another column Redshift

I have following table
]1
want to add date range for each user
How to achieve this:
if this is possible from query in Redshift then that be useful
If not, efficient way to create this in python pandas as data is having 8lk records
Given this dataframe df:
userid username
0 1 a
1 2 b
2 3 c
you can use numpy repeat and tile:
dr = pd.date_range('2020-01-01','2020-01-03')
df = pd.DataFrame(np.repeat(df.to_numpy(), len(dr), 0), columns=df.columns).assign(date=np.tile(dr.to_numpy(), len(df)))
Result:
userid username date
0 1 a 2020-01-01
1 1 a 2020-01-02
2 1 a 2020-01-03
3 2 b 2020-01-01
4 2 b 2020-01-02
5 2 b 2020-01-03
6 3 c 2020-01-01
7 3 c 2020-01-02
8 3 c 2020-01-03
In Sql this is simple too - just cross join with the list of dates you want to add to each row (replicate rows). You can see that in your example that 3 rows and 3 dates results in 9 rows. (untested explanatory code:)
select userid, username, "date" from <table> cross join (select values ('2020-01-01'::date), ('2020-02-01'::date), ('2020-03-01'::date));
Now the problem with simple approach is that if you are dealing with large tables and long lists of dates the multiplication will kill you. 10 billion rows by 5,000 dates is 15 trillion resulting rows - making this will take a long time and storing it will takes lots of disk space. For small tables and short lists of dates this works fine.
If you are in the "big" side of things you will likely need to rethink what you are trying to do. Since you are using Redshift there is a possibility that you may need to do this.

Using sequences for every row in a sql-server table

We have a table Property in our database containing a counter in every row stored in the NextVoucherNumber integer column. There are about 2000 rows there.
ID ... {other columns} ... NextVoucherNumber
-----------------------------------------------
1 112
2 34
3 29
4 9456
.... ....
2000 233
We have an issue with a concurrent access to the table.
To improve the performance we would like to extract those columns to a separate table PropertyVoucherNumbers with a 1:1 relation between the rows.
ID NextVoucherNumber
------------------------
1 112
2 34
3 29
4 9456
.... ....
2000 233
Alternatively, we could maintain sequences for every row.
Seq_VoucherNumber_1, Seq_VoucherNumber_2, ... Seq_VoucherNumber_2000.
Looks like the same triggers just a little dynamic SQL there.
Could you please describe what the problems we will face using the second solution?
Can you suggest any better solution?

Access 2010: data rows as column headings?

I'm using MS Access 2013.
I need to display AND EDIT a grid of data based on three tables:
UnitID UnitName
1 Unit1
2 Unit2
3 Unit3
ProdID ProdName
1 Furniture
2 Food
3 Other
UnitID ProdID Forecast
1 1 10
1 2 20
1 3 30
2 1 40
2 2 50
2 3 60
3 1 70
3 2 80
3 3 90
so it looks like:
Unit1 Unit2 Unit3
Furniture 10 40 70
Food 20 50 80
Other 30 60 90
Furthermore, the query must be editable (user should be able to enter his forecast data).
Any idea how to do this in Access 2010? I've looked into pivots and crosstab queries, but they use aggregate functions and thus aren't editable... but in my case, the source of the data is unambiguous so an editable option should exist? Anyone has an idea how to get the data in editable format?
Thanks!
Jur.
Create a temp table and fill it with the data from your crosstab query. Use that table as the source for a form, which will be editable. In the beforeupdate event of the form, add code to update the original source table.
Thanks all,
distributing any kind of exe is not an option due to security measurements in the client's environment (they can run Office and little else). So I'm going for the temp table option anyway... any pointers for a template solution to modify to my needs?
Thanks again!
Jur.

Microsoft Access 2007 Report with Conditional Columns

I am looking to make a very simple report to condense and show data side by side. All of the examples of reports I find are only row by row.
The query I will use will only have three schema "Company, Model, Total"
The format I am trying to get to is
Company Model Total Company Model Total
A 123 2 B 123 4
A 222 3 B 333 3
A 444 7 B 444 7
The idea is to present the information in a way that multiple companies side by side can compare inventory of the same model and find discrepencies. Ideally the report would eventually group all Model's that span every company at the top, but thats a next generation problem.
I have attempted conditional formating on multiple "Company" boxes, but the conditionals do not seem to be applying properly or for some reason every "Company" box is adopting the same conditionals.
I think you want a crosstab query grouping by model (the rowHeader), company as the column header, and first(total) as the value.
The results should look like
model A total B total
123 2 4
222 3
333 3
444 7 7
then you can create another query based on the crosstab results to calculate the difference between company totals, if you want.
You have to do this in two steps:
Build a query that gives you:
Company Model Total
A 123 2
A 222 3
A 444 7
B 123 4
B 333 3
B 444 7
Let's call q this query.
Build a second query
SELECT q1.Company, q1.Model, q1.Total, q1.Company, q2.Model, q2.Total
FROM q AS q1 INNER JOIN q AS q2 ON q1.Model = q2.Model
WHERE q1.company < q2.company;
This will give you:
A 123 2 B 123 4
A 444 7 B 444 7
(There are no matching data for models 222 and 333)

MS Access CrossTab query - across 3 tables

I have the following 3 tables:
1) Sweetness Table
FruitIndex CountryIndex Sweetness
1 1 10
1 2 20
1 3 400
2 1 50
2 2 123
2 3 1
3 1 49
3 2 40
3 3 2
2) Fruit Name Table
FruitIndex FruitName
1 Apple
2 Orange
3 Peaches
3) Country Name Table
CountryIndex CountryName
1 UnitedStates
2 Canada
3 Mexico
I'm trying to perform a CrossTab SQL query to end up with:
Fruit\Country UnitedStates Canada Mexico
Apple 10 20 400
Orange 50 123 1
Peaches 49 40 2
The challenging part is to label the rows/columns with the relevant names from the Name tables.
I can use MS Access to design 2 queries,
create the joins the fruit/country names table with the Sweetness table
perform crosstab query
However I'm having trouble doing this in a single query. I've attempted nesting the 1st query's SQL into the 2nd, but it doesn't seem to work.
Unfortunately, my solution needs to be be wholly SQL, as it is an embedded SQL query (cannot rely on query designer in MS Access, etc.).
Any help greatly appreciated.
Prembo.
How about:
TRANSFORM First(Sweetness.Sweetness) AS FirstOfSweetness
SELECT Fruit.FruitName
FROM (Sweetness
INNER JOIN Fruit
ON Sweetness.FruitIndex = Fruit.FruitIndex)
INNER JOIN Country
ON Sweetness.CountryIndex = Country.CountryIndex
GROUP BY Fruit.FruitName
PIVOT Country.CountryName;
I hate to rely on an outside post and present it as my answer, but this is a pretty steep topic and I can't do it justice. So I suggest you look at this article.