I have mysql table with the following structure. All records are static and only for read, and had been imported from CSV so all year, month, day are in correct sequence as per I created them. (No, ID column in this table because I only access data by year, month and day)
mysql table 'daily'
year month day data
1990 01 01 xxxxxxxxxxxxx
1990 01 02 eeeeeeeeeeeee
1990 01 03 rrrrrrrrrrrrr
1990 01 04 ttttttttttttt
.
.
.
Now, I can access the records by simple select statement as below
select * where year=1990 and month=1 and day=03 limit 1
But how can I select the query row + 3 or any number of adjacent rows (before or after the query row)? And I don't want to use ID if there is better solutions.
I would consider using the DATE type instead of separate columns for year, month, and day. Then you can use DATEADD and related functions to find the day you want.
http://dev.mysql.com/doc/refman/5.1/en/datetime.html
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
Related
I have the scenario where I need to load data for next quarter ,this data should be insert only and from next day
data should be incremental load.For example for quarter 1 jan to 6 march .On 1 jan we have loaded historical load or first time insert and on 2 jan onwards it in incremental load. Now on 7 march we want fresh insert and from 8 march incremental load will run on newly insert data on 7 march. Like we want to lock the data from the quarter 1 jan to 6 march and fresh insert should happen on 7 march and 8 march incremental load should run on data loaded on 7 march. How to achieve this in ssis?
The best way to do this is create a calendar table and have a special column within that table that maps every single date to a 'freeze date' attribute.
So I leave you to do some research on calendar tables.
In the meantime, without a calendar table, here is something to get you started.
Firstly, this expression gives you the first month in the current quarter. So if today is anywhere within Jan - Mar, this expression gives you 1. If today is anywhere within Oct-Dec, it gives you 10
SELECT (((MONTH(GETDATE()))-1)/3)*3+1 As FirstMonthInCurrentQuarter
Now we convert that number to an actual date on the first of the month.
First, generate a numeric representation:
SELECT
YEAR(GETDATE()) * 10000 +
((((MONTH(GETDATE()))-1)/3)*3+1) * 100 +
1
We just convert that to an actual date:
SELECT
CONVERT(
DATE,
CAST(
YEAR(GETDATE()) * 10000 +
((((MONTH(GETDATE()))-1)/3)*3+1) * 100 +
1
AS VARCHAR(8)),
112)
That's a monstrous expression that can be replaced with a calendar table.
If you run it right now you'll get 1 Jan 2019. If you run that on 5th April you'll get 1st April. Hopefully you understand how that shuffles along automatically.
Now we use that date to decide what to load into your table.
DECLARE #LoadDate DATE
SET #LoadDate =
CONVERT(
DATE,
CAST(
YEAR(GETDATE()) * 10000 +
((((MONTH(GETDATE()))-1)/3)*3+1) * 100 +
1
AS VARCHAR(8)),
112)
-- Delete all the data in the target table after this date:
DELETE TargetTable WHERE TransactionDate >= #LoadDate;
-- Use your ETL tool to load this in:
INSERT INTO TargetTable (TransactionDate, Amount, Account)
SELECT TransactionDate, Amount, Account
FROM SourceTable WHERE TransactionDate >= #LoadDate;
You have nowhere near enough information in your question for a meaningful answer, but maybe this will give you an idea
95% chance you never return though.
I want to calculate some percentage etc. between 1st and 13th of every month.
Like JAN 1st to JAN 13th Do some calculation. Similarly for every month I have to make the calculation for the first 13 days. How to get the first 13 days or any number of days in MySQL?
Assuming that you have a column of date data type it could be like this:
SELECT MONTH(date_column) AS mnth,
SUM(etc) AS col1,
SUM(etc2) AS col2
FROM tbl
WHERE DAY(date_column) BETWEEN 1 AND 13
GROUP BY MONTH(date_column)
I have a mysql database with a table in it. This table consists of the some of the following information. It has values in one column with months Jan-May. So five months. On the adjacent column, there are "Counts" with integer values to each month. Bear in mind that there can be duplicate values of the months. So, for example, a snippet of the table could read
January | 5
January | 10
February | 1
March | 20
April | 23
April | 34
April | 43
May | 9
There are a lot more records (160). Say the average of the month is running some sql command like
select month, avg(count) from tablename group by month. However, this divides the sum of counts for each month by the number of records. A true average would divide the sum of the counts by the number of days in each month. So I have the following statements,
select month, sum(count)/31 from trendsummary.traffictype where month like 'January';
select month, sum(count)/28 from trendsummary.traffictype where month like 'February';
select month, sum(count)/31 from trendsummary.traffictype where month like 'March';
select month, sum(count)/30 from trendsummary.traffictype where month like 'April';
select month, sum(count)/31 from trendsummary.traffictype where month like 'May';
This gives me the averages for the counts for each month. So the question is...what would be the syntax if I wanted an average of the averages of Jan-April? So... I want to have statements that would take the averages (based on the number of days of the month) for each of the months, and then take the average of the averages for January, February, March, And April and spit that value out? How would one go about this? Thanks!
you can try that :
select month, sum(count)/(31+28+31+30)
from trendsummary.traffictype
where month in ( 'January' , 'February','March','April' );
Union the selects and enclose them in parentheses and treat that as you data source as in this example:
select avg(*) from (
select month, sum(count)/31 as average from ...
union select ...
union select ...
)
remember that most sql engines will require to name the computed expression column like I did (as average) at least in the first select of all union selects.
I'm working on a query to get records based on two dates, start and end dates.
What I need to obtain are records that are span some or all of the given period, in other words the start date maybe before the parameter date but less than the end date or start after the start date and end after the end date.
I.e. Start date = 01 Oct 12 and end date 31 Oct 12. I would like to capture records where start date is before 1 Oct but spans this period whether it finishes in November or mid October. As well as records that are between 01 Oct 12 and 31 Oct 12.
In reality I need the records that exclude this period, but first need to make sure I'm getting this dataset correct.
I'm starting with this simple data set stored in MyTable, with both start_date and end_date as Date/Time data type.
id start_date end_date
1 9/29/2012 9/30/2012
2 9/29/2012 10/2/2012
3 9/29/2012 11/1/2012
4 10/2/2012 11/1/2012
5 11/1/2012 11/2/2012
Running the query below, and supplying 2012-10-01 and 2012-10-31 for the range_start and range_end parameters, gives me this output result set.
id start_date end_date
2 9/29/2012 10/2/2012
3 9/29/2012 11/1/2012
4 10/2/2012 11/1/2012
If this is not similar to what you wanted, please edit your question to show us a brief sample set of input data and the output you want from that sample.
Also, note the time components of my start_date and end_date values were all midnight. If your counterparts include any other times of day, you will need to revise the query to deal with them.
This is the SQL from the query I used:
PARAMETERS range_start DateTime, range_end DateTime;
SELECT m.id, m.start_date, m.end_date
FROM MyTable AS m
WHERE
m.start_date Between [range_start] And [range_end]
OR m.end_date Between [range_start] And [range_end]
OR (m.start_date<[range_start] AND m.end_date>[range_end]);
I have a MySQL table of photovoltaic electricity generation data (pvdata) from which I need to produce a monthly summary table. A simplified table is shown:
id date time pvdata
1 2012-01-01 10:00 50
1 2012-01-31 12:00 60
1 2012-02-10 13:00 70
2 2012-02-08 10:00 12
2 2012-03-20 10:00 17
The monthly summary table needs to show the cumulative generation for all systems in the database, regardless of whether I have received data for that month, so for example month 3 below contains the total generation from id = 1 (data received in month 2).
Also there may be more than one data point for an id in the same month, so the report must report the max(data) for the month.
year month cum_data
2012 1 60
2012 2 82
2012 3 87
I am pretty new to this, so have struggled for a while. The best I can come up with shows the cumulative total for the month, but without including the cumulative total for ids for which there is no data in the current month:
CREATE TEMPORARY TABLE intermed_gen_report
SELECT year(date) AS year, month(date) AS month, id, max(pvdata) AS maxpvdata
FROM pvdata
GROUP BY id, year(date), month(date)
ORDER BY year(date), month(date);
SELECT year, month, SUM(maxpvdata) AS cum_data
FROM intermed_gen_report
GROUP BY year, month
ORDER BY year, month;
Giving:
year month cum_data
2012 1 60
2012 2 82
2012 3 17
I think the problem is one kind of like this http://www.richnetapps.com/using-mysql-generate-daily-sales-reports-filled-gaps/ - you will want to create a table (possibly temporary) with dates (or year / month values). However that example leaves zeros where there is no data - I think you will want to do a join on a subselect that returns the most recent data before that date (or year/ month value).
I agree I think with what Aerik suggests. You will want to join your data of what is usually called a 'date dimension table'. You can find lots of examples on how to populate said table. This is a common technique in data warehousing.
You can also do what you need in one select using sub selects. Take a look at some of the previous threads like: generate days from date range