Rearrange the position of the values in the table - mysql

I am using MYSQL. I have a table containing a start date and an end date for a schedule.
| StartDate | FinishDate |
|Feb 1, 2016 11:50 AM |Feb 2, 2016 3:37 PM |
|Feb 2, 2016 4:29 PM |Feb 3, 2016 8:16 PM |
|Feb 3, 2016 8:17 PM |Feb 3, 2016 8:34 PM |
What I was hoping to do is to get the dates where there are no schedule entries.
The easiest way I thought of is to generate a new table wherein the values in the FinishDate and StartDate will be rearranged in this format (The FinishDate value in the first row, second column will be the value in the first row, first column, while the StartDate value in the second row, first column will be transported to first row, second cloumn, and so on):
Desired Output
Without allocation:
| StartDate | FinishDate |
|Feb 2, 2016 3:37 PM |Feb 2, 2016 4:29 PM |
|Feb 3, 2016 8:16 PM |Feb 3, 2016 8:17 PM |
|Feb 3, 2016 8:34 PM | - |
How can I achieve the desired output? Thank you very much in advance.

MySql doesn't have window functions, so generating this kind of result is always tricky. One possibility is:
SELECT
t1.FinishDate StartDate
, MIN(t2.StartDate) FinishDate
FROM table t1
LEFT JOIN table t2 ON t2.StartDate > t1.FinishDate
GROUP BY 1
This will work well if your date columns are indexed and you have relatively small number of rows to process.

Related

How to delete duplicate rows with one condition that the other column is null in Mysql

I have a table looks like below
Lead_id Email Touchpoint_Date
null | e#gmail.com | August 16, 2014 8:58:11 PM
111 | e#gmail.com | August 16, 2014 8:58:11 PM
222 | e#gmail.com | August 5, 2014 4:12:07 AM
null | f#gmail.com | August 18, 2014 9:58:11 AM
111 | f#gmail.com | August 18, 2014 9:58:11 AM
And I would like to delete all the rows that have same date (like row 1 and row 2, row 4 and row 5) and remain the row with lead_id not null. How should I do that in Mysql?
You can add this line to delete the duplicates dates
ALTER IGNORE TABLE table_name ADD UNIQUE INDEX(date);
This query will delete the duplicates values in your table and after you can drop drop it if you want

php mysql command for daily report

I have a mysql table with some entries. sample data
nid | news_date
1 | 16 July 2015, 2:31 pm
2 | 16 July 2015, 2:31 pm
3 | 17 July 2015, 12:31 pm
4 | 18 July 2015, 4:28 pm
5 | 20 July 2015, 12:31 pm
I want daily report, and i tried with this sql command
SELECT count(nid), DATE(news_date)
FROM tbl_news
GROUP BY DATE(tbl_news.news_date);
But i am getting output as
count(nid) | DATE(news_date)
5 | NULL
But i want daily record count report, Anybody help.
Please try this query:-
SELECT count(nid), news_date
FROM tbl_news
GROUP BY (STR_TO_DATE(tbl_news.news_date, '%d %M %Y')) ;
I have removed the date keyword.

STR_TO_DATE() returns invalid date

I was given a job to create a new table in the database with correct data type. Here are sample records:
RegisteredMonthYear
------------------------
May 2011
March 1998
January 2000
Before I will insert the converted value I tried to convert it using STR_TO_DATE() to check if the values are correct and the result were exactly not I want. This is my query:
SELECT RegisteredMonthYear,
STR_TO_DATE(RegisteredMonthYear, '%M %Y') NewDate,
STR_TO_DATE(CONCAT(RegisteredMonthYear, ' 01'), '%M %Y %d') newDate2,
STR_TO_DATE(RegisteredMonthYear, '%M %Y') + INTERVAL 1 DAY newDate3
FROM TableName
+---------------------+---------------------------------+--------------------------------+----------+
| REGISTEREDMONTHYEAR | NEWDATE | NEWDATE2 | NEWDATE3 |
+---------------------+---------------------------------+--------------------------------+----------+
| May 2011 | April, 30 2011 00:00:00+0000 | May, 01 2011 00:00:00+0000 | (null) |
| March 1998 | February, 28 1998 00:00:00+0000 | March, 01 1998 00:00:00+0000 | (null) |
| January 2000 | December, 31 1999 00:00:00+0000 | January, 01 2000 00:00:00+0000 | (null) |
+---------------------+---------------------------------+--------------------------------+----------+
see here for demo: http://www.sqlfiddle.com/#!2/89a67/7
As you can see, column NEWDATE is one day behind. Why are the result like this?
When I tried to concatenate 01 in the string in column NEWDATE2 the result is as expected. Going back on NEWDATE column, I tried to add one day thinking that it will give exact value in column NEWDATE3 but the result is NULL.
Any idea about this?
You can use following formula (SQLFiddle):
SELECT date(str_to_date(RegisteredMonthYear, '%M %Y'))
+ interval 1 day
FROM tablename
I have added extra DATE() call on top of STR_TO_DATE() - but it makes all the difference.
But in general I agree that this is one more really weird MySQL gotcha.
For example, in PostgreSQL, you don't need to add 1 day and you don't need extra casts, simple to_timestamp is enough:
SELECT to_timestamp('May 2011', 'Mon YYYY');
2013-05-01 00:00:00-07

SSRS: Pivoting columns

I've got a list of raw data which is passed to SSRS from a stored procedure. I have a matrix which then pivots the data.
For example:
Raw data
WeekNumber Date
1 Mon 10th Dec
1 Tue 11th Dec
1 Wed 12th Dec
2 Mon 17th Dec
When pivoted, it becomes the following for the column names
Mon 10th Dec | Tue 11th Dec | Wed 12th Dec | Mon 17th Dec
Is it possible to have a pivot with a where condition? In this example say,
I'd want it to look like
Mon 10th Dec | Tue 11th Dec | Wed 12th Dec
and then another column with Mon 17th Dec since the WeekNumber is 2
I'm not sure I understand your question. But anyway, perhaps you could consider doing the pivot in your stored procedure as per :
http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
My secret to success when using reporting tools is to solve complex problems at the data level, rather than trying to get the reporting tool to do it.
Yes, this is not difficult.
What you are calling a pivot in SSRS is really just a column group. You can add either a filter or a parent group to your column group to filter out WeekNumber <> 2 or group above by WeekNumber. With a parent group you could get results like:
WeekNum: 1 | Total for week | |WeekNum: 2 | Total for week |
Mon 10th Dec | Tue 11th Dec | Wed 12th Dec | | |Mon 17th Dec
20 | 25 | 10 | 55 | | 15 | 15

Followup: how to model discount on items in a database?

I am building an ecommerce site and would like to offer discounts on certain items for a limited time. I would like to display how much discount we are offering per product. Hence, I need two values per product, original price and the discounted price for the given duration.
This is in followup to an answer for the question I asked
Schema:
Product
productId
Name
ProductPricing
productId (FK)
startDateTimeStamp
endDateTimeStamp
price
original price only applicable if we use approach A (comes later on)
Data:
Product:
1 | Apple
2 | Banana
T1: Dec 21, 2011: No deals at this time
ProductPricing
1 | Dec 20, 2011, 00:00 | Jan 1, 2038, 00:00 | 10$ | 10$
2 | Dec 20, 2011, 00:00 | Jan 1, 2038, 00:00 | 20$ | 20$
T2: Dec 24, 2011: Deal! Apply discount of 25% on apples from Dec 25, 14:00 - Dec 26, 14:00
Approach A.
- Query updates apple prices for the given duration
ProductPricing
1 | Dec 25, 2011, 14:00 | Dec 26, 2011, 14:00 | 7.5$| 10$
2 | Dec 20, 2011, 00:00 | Dec 25, 2038, 00:00 | 20$ | 20$
Approach B.
- Query adds another record with apple prices for the given duration
ProductPricing
1 | Dec 20, 2011, 00:00 | Jan 1, 2038, 00:00 | 10$ | 10$
2 | Dec 20, 2011, 00:00 | Dec 25, 2038, 00:00 | 20$ | 20$
1 | Dec 25, 2011, 14:00 | Dec 26, 2011, 14:00 | 7.5$| 10$
T3: Dec 27, 2011 - Options
Approach A.
At this time, the deal is expired, should I reset the endTimeStamp using a trigger ?
Approach B.
Should I delete the most recent record for the product for which the deal just expired ?
The design of the ProductPricing table allows us to never have to delete old pricing data (sometimes management wants a report based on that data). With what you have described above, you'd start like this (I changed the starting date just so it's easy to pick out that yes, this was the original price when the system went into place):
ProductPricing
1 | Jan 1, 1970, 00:00:00 | Jan 1, 2038, 00:00:00 | 10$ | 10$
Now let's say you give a discount price on your apples, and you wanted to be proactive and set up the system for when the sale was over:
ProductPricing
1 | Jan 1, 1970, 00:00:00 | Dec 20, 2011, 00:00:00 | 10$ | 10$
1 | Dec 20, 2011, 00:00:01 | Dec 26, 2011, 00:00:00 | 7.5$ | 10$
1 | Dec 26, 2011, 00:00:01 | Jan 1, 2038, 00:00:00 | 10$ | 10$
What we did here was:
Update the existing record with the 2038 timestamp, changing the endDateTimeStamp field to reflect the beginning of the sale
Insert a new record to define the sale
Insert another new record to reflect the normal price again
With no overlapping timestamps, you're guaranteed to get a single record when you query the database for your price. Thus,
SELECT p.Name, pp.price, pp.original_price
FROM Product p
INNER JOIN ProductPricing pp ON pp.productId = p.productId
WHERE NOW() BETWEEN pp.startDateTimeStamp AND pp.endDateTimeStamp
would get you a product list with current pricing.