SQL Server 2008: Creating dynamic column names - sql-server-2008

I have a problem that I cannot solve. I work on Microsoft SQL Server 2008 and I have a table with four columns
Id
Date (2013-07, 2013-08, 2011-03, etc)
Amount 1 (100, 150, etc.)
Amount 2 (100, 80, etc.)
If Amount 1 > 150 then I need to create new columns with the values in Date as column names and distribute Amount 2 into 6 (date) periods starting one month after the Date value.
It should look like this:
Id Date Amount 1 Amount 2
----------------------------------
1 2013-07 160 60
2 2013-10 180 80
Id Date Amount 1 2013-08 2013-09 2013-10 2013-11 2013-12 2014-01 ...
--------------------------------------------------------------------------------
1 2013-07 160 10 10 10 10 10 10
2 2013-10 180 20 20 20...
I don't know how to do this and any help is highly appreciated! Thank you!

The table itself should not have these additional columns because that would be a denormalized table structure. That's a poor way to store data in many cases. But you can easily do a query against your existing table that will return the additional columns in the form you want, so that you can display it this way. Check out PIVOT and UNPIVOT.

Related

SQL Query - Pull data from ambiguous column names for growth/decline %

Re-post due to bad data set and bad formatting. I am trying to divide data from two separate tables that have ambiguous column names.
I am newer to SQL, I know it should be simple, however I just can not figure it out. So far I have tried to rename columns, alias columns, union the table, and select multiple data sets.
I keep hitting roadblocks.
I am trying to measure growth or decline week over week. Ideally I want to take the total sales for Plates and do the following equation: (75/100-1) which would equal a -25% decline from last week.
What would be the best way to go about this?
The two example tables are below
LastWeekData
Product Day Month TotalSales
Plates 7 3 $100
Spoons 7 3 $150
Forks 7 3 $120
CurrentData
Product Day Month TotalSales
Plates 14 3 $75
Spoons 14 3 $100
Forks 14 3 $115
You can use table alias to differentiate the table columns that you want to display. See demo here: http://sqlfiddle.com/#!9/0b0d81/29
select cur.Product,
cur.Day,
cur.Month,
cur.TotalSales as currweek_TotalSales,
pre.TotalSales as lastweek_TotalSales,
round((cur.TotalSales/pre.TotalSales-1)*100) as percent_change
from CurrentData as cur
inner join LastWeekData as pre
on pre.product=cur.product
where datediff(str_to_date(concat_ws('-','0001',cur.month,cur.day),'%Y-%m-%d'),
str_to_date(concat_ws('-','0001',pre.month,pre.day),'%Y-%m-%d'))
= 7
Result:
Product Day Month currweek_TotalSales lastweek_TotalSales percent_change
Plates 14 3 75 100 -25
Spoons 14 3 100 150 -33
Forks 14 3 115 120 -4

Create a query to return number of produced products based on date in Microsoft Access

I want to create a query to get the total number of produced products for each day in Microsoft Access.
Here are the few rows of my table as a sample:the table's name is Orders
ordernumber number of products Date
100 2 11-May-16
101 1 11-May-16
121 2 24-May-16
122 3 24-May-16
131 1 25-May-16
105 3 11-May-16
127 1 24-May-16
135 2 25-May-16
The desired output is :
TotalNoProducts Date
6 11-May-16
6 24-May-16
3 25-May-16
This is one of the more basic aggregate queries:
SELECT SUM([number of products]) As TotalNoProducts, CDate(Int([Date])) As TheDate
FROM Orders
GROUP BY CDate(Int([Date]))
Note that you can also build this query through the query builder, which is usually easier for beginners than using SQL

mysql - get the average of the output average

I have 3 table. final,milestone and milestonewp consider that the three tables is foreigned key like milestonewp<--FK--milestone<--FK--Final .Then I have a column for determining the average of the milestonewp for a certain foreign key. Then getting that average to be average again to be displayed to the final table.Here is my visual representation
milestonewp
condition | mile_id
20 1
20 1
30 1
21 2
21 2
31 2
40 3
30 3
50 3
How can I average the average that the chart above will produce?
I'm trying to work on this
select avg(milewp_condition)
from logs_pms_r_milestone_wp
where mile_id=1;
but i dont have any idea how it can produce for the other mile_id
EDIT
The above code will produce something like this
avg(milewp_condition)
0
0
0
so then, i also want to average that 3 rows.
If I understand well this should be what you look for:
SELECT AVG(milewp_condition)
FROM logs_pms_r_milestone_wp
GROUP BY mile_id;
If you want to average all, just do:
SELECT AVG(milewp_condition)
FROM logs_pms_r_milestone_wp;
Regards

Mysql table design advice

I have a general question about MySQL database table design. I have a table that contains ~ 650 thousand records, with approximately 100 thousand added per year. The data is requested quite frequently, 1.6 times per second on average.
It has the following structure right now
id port_id date product1_price product2_price product3_price
1 1 2012-01-01 100.00 200.00 155.00
2 2 2012-01-01 NULL 150.00 255.00
3 3 2012-01-01 300.00 NULL 355.00
4 1 2012-01-02 200.00 250.00 355.00
5 2 2012-01-02 400.00 230.00 255.00
Wouln't it be better to store the data in this manner?
id port_id date product price
1 1 2012-01-01 1 100
1 2 2012-01-01 1 200
1 3 2012-01-01 1 300
1 1 2012-01-02 1 240
Advantages of the alternative design:
with the second design we don't have to store NULL values (if there is no such product in the port)
we can add new products easily - comparing to the first design, where each new product requires a new column
Disadvantages of the alternative design:
The number of records will increase from 650 000 to 650 000 * number_of_products minus all NULL records; that will be approximately 2.1 million records.
In both cases we have id column as PRIMARY_KEY and UNIQUE key on combination of port_id and date.
So the question is: which way to go? Disk space does not matter, the speed of the queries is the most important aspect.
Thank you for your attention.
It seams, that will depend on definition of product table.
If product table is statically compound of maximum three parts, then changing the current design won't help much.
Although the current design smells bad but that will be a business dependent analysis.
BTW change must be done with caution on the side effects with product table and its usages.

How to setup MySQL table to follow a variable over time?

Say I have several registered users in my website.
Users are saved on a single table 'users' that assigns a unique id for each one of them.
I want to allow my users to track their expenses, miles driven, temperature, etc.
I can't be sure each user will always enter a value for all trackable variables when they login -- so an example of what could happen would be:
'example data'
user date amount miles temp etc
1 3/1/2010 $10.00 5 54
2 3/1/2010 $20.00 15
1 3/12/2010 5 55
1 3/15/2010 $10.00 25 51
3 3/20/2010 45
3 4/12/2010 $20.00 10 54
What is the best way to set up my tables for this situation?
Should I create a table exclusive to each user when they register? (could end up with thousands of user-exclusive tables)
'user-1 table'
date amount miles temp etc
3/1/2010 $10.00 5 54
3/12/2010 5 55
3/15/2010 $10.00 25 51
'user-3 table'
date amount miles temp etc
3/20/2010 45
4/12/2010 $20.00 10 54
and so on...
Should I create a single table that is essentially the same as the example data above? (could end up with a gigantic table that needs to be combed to find rows with requested user id's).
'user data table'
user date amount miles temp etc
1 3/1/2010 $10.00 5 54
2 3/1/2010 $20.00 15
1 3/12/2010 5 55
1 3/15/2010 $10.00 25 51
3 3/20/2010 45
3 4/12/2010 $20.00 10 54
Any suggestions?
Databases are built to handle similar data as a set together.
What you want is a single user-data-table, with multiple users in the same table split by user_id. You might want to further normalize that though, so that it stores:
user date type units
1 3/1/2010 dollars 10.00
1 3/1/2010 miles 5
1 3/1/2010 temp 54
2 3/1/2010 dollars 20.00
2 3/1/2010 miles 15
1 3/12/2010 miles 5
1 3/12/2010 temp 55
etc
Or even further if the user+date makes a specific trip
trip-table
tripid user date
========= ======== =========
1 1 3/1/2010
type-table
typeid description
========= ============
1 dollars
2 miles
etc
trip-data
tripid type units
========= ======== =======
1 1 10.00
1 2 5
etc
However, if you will always (or almost always) show your data in the form as entered, with the data pivoted on all the input columns (like a spreadsheet), then you would be better off sticking to the un-normalised form for brevity, programmability and performance.
could end up with a gigantic table that needs to be combed to find rows with requested user id's
Assuming you employ indexes properly and judiciously, modern RDBMS are built to handle gigantic amounts of data. The indexes allow the queries to seek only the data it needs, so there is normally little penalty in keeping it all in one table.
No, just create one table with all possible nullable fields. If user hasn't filled that parameter - then just keep NULL value there.
could end up with a gigantic table that needs to be combed to find rows with requested user id's
Yes, and the query will be fast enough if you'll specify an index for user_id field (for queries like WHERE user_id = 42)