MySQL compare dates in a column to today - php

I have a table of around 6000 records with a date column amongst other columns which represent the deadline for a query. I need to compare the date in the column to todays date which I understand is done something like:
SELECT DATEDIFF(DATE_TO_COMPARE, CURDATE());
However, I then have another comlumn I want to set to that date difference. So for each date, I need to compare, insert the difference in the column difference_in_days, iterate to the next date and repeat.
I am also invoking this function whenever a certain page on my site is loaded using AJAX and PHP/PDO
My SQL knowledge isn't that extensive, how can I achieve this.
Table is kinda of like
field 1, field2, field 3, date_to_compare, field 4, field 5, difference_in_days
| | | | 2016-04-20 | | | |
| | | | 2016-04-25 | | | |
| | | | 2016-04-22 | | | |
| | | | 2016-04-27 | | | |
| | | | 2016-04-29 | | | |

Sonds like you want to do an update?
UPDATE table_name
SET difference_in_days = DATEDIFF(date_to_compare, CURDATE());
This will update every record in the table to the diff of the current date.
However, this will require you running the update every day, if you want that column to maintain relevance.
Alternative Approach:
If you're not querying this a lot, you may be better off using a view, which will update real-time every time you query it.
CREATE VIEW diff_view_name AS
SELECT *, DATEDIFF(date_to_compare, CURDATE()) AS difference_in_days
FROM table_name;
Then you could query it using:
SELECT * FROM diff_view_name;

Related

How to update new value to current field and transfer current value to old field?

I have a MySQL table that updates from an API daily, but now I want to track a specific field that has been updated from the API. I want to update the row with the current field(value) change and keep the old field(value) in another field.
Could somebody please point me in the right direction and what would be the best practice for this?
Table (original)
---------------------------------
|ID | Input Date | Expired Date |
---------------------------------
| 2 | 2017-05-17 | 2017-12-19 |
---------------------------------
| 3 | 2017-07-09 | 2018-05-19 |
---------------------------------
Table when updated (current)
---------------------------------
|ID | Input Date | Expired Date |
---------------------------------
| 2 | 2017-05-17 | 2018-05-28 | <----- ID 2: Expired Date updated
---------------------------------
| 3 | 2017-07-09 | 2018-05-19 |
---------------------------------
Table updated and keeps old field value
------------------------------------------------
|ID | Input Date | Expired Date | Old Exp Date |
------------------------------------------------
| 2 | 2017-05-17 | 2018-05-28 | 2017-12-19 |
------------------------------------------------
| 3 | 2017-07-09 | 2018-05-19 | |
------------------------------------------------
I hope this made sense a little, please help..Thank you so much:)
You may create a trigger for it
CREATE TRIGGER date_updated BEFORE UPDATE ON <your table name>
FOR EACH ROW SET <old exp date column> = OLD.<expired date column>
In PostgreSQL, you can use the RETURNING clause
UPDATE <table name> SET <column> = <value> RETURNING <column>
I found out 2 ways of doing this:
A. Using 2 queries to the database
- update the Old Exp Date with the Expired date value from table
- update the Expired date with the new value from the API
B. Using a single query
- you can try to set both fields at once but you should test it
- it is like SET Old Exp Date = Expired date, Expired date = API_VALUE
Some implementations don't have the same UPDATE order:
sql-update-order-of-evaluation
You should test it to see how it works on your system. If it works then you should decide if there is any risk of portability issues.
Kind Regards,
Lin
You can simply try the mysql query similar like this,
UPDATE your_table_name
SET `Old Exp Date` = `Expired Date`,
`Expired Date` = "$api_value";

Select MySQL return table header as well table body in one query

Hello I am facing hard time trying to realized this task. The problem is that I am not sure in which way this have to be proceeded and couldn't find tutorials or information about realizing this type of task.
The question is I have 2 tables and one connecting table between the two of them. With regular query usually what is displayed is the table header which is known value and them then data. In My case I have to display the table horizontally and vertically since the header value is unknown value.
Here is example of the DB
Clients:
+--------+------ +
| ID | client|
+--------+------ +
| 1 | Sony |
| 2 | Dell |
+--------+------ +
Users:
+--------+---------+------------+
| ID | name | department |
+--------+--------+-------------+
| 1 | John | 1|
| 2 | Dave | 2|
| 3 | Michael| 1|
| 4 | Rich | 3|
+--------+--------+-------------+
Time:
+--------+------+---------------------+------------+
| ID | user | clientid | time | date |
+--------+------+---------------------+------------+
| 1 | 1 | 1 | 01:00:00 | 2017-01-02 |
| 2 | 2 | 2 | 02:00:00 | 2017-01-02 |
| 3 | 1 | 2 | 04:00:00 | 2017-02-02 | -> Result Not Selected since date is different
| 4 | 4 | 1 | 02:00:00 | 2017-01-02 |
| 5 | 1 | 1 | 02:00:00 | 2017-01-02 |
+--------+------+---------------------+------------+
Result Table
+------------+--------+-----------+---------+----------+
| Client | John | Michael | Rich | Dave |
+------------+--------+-----------+---------+----------+
| Sony |3:00:00 | 0 | 2:00:00 | 0 |
+------------+--------+-----------+---------+----------+
| Dell | 0 | 0 | 0 | 2:00:00 |
+------------+--------+-----------+---------+----------+
First table Clients Contains information about clients.
Second table Users Contains information about users
Third Table Time contains rows of time for each users dedicated to different clients from the clients table.
So my goal is to make a SQL Query which will show the Result table. In other words it will select sum of hours which every user have completed for certain client. The number of clients and users is unknown. So first thing that have to be done is Select all users, no matter if they have hours completed or not. After that have to select each client and the sum of hours for each client which was realized for individual user.
The problem is I don't know how to approach this situation. Do I have first to make one query slecting all users then foreach them in the table header and then realize second query selecting the hours and foreaching the body conent, or this can be made with single query which will render the whole table.
The filters for select command are:
WHERE MONTH(`date`) = '$month'
AND YEAR(`date`) ='$year'
AND u.department = '$department'
Selecting single row for tume SUM is:
(SELECT SUM( TIME_TO_SEC( `time` ) ) FROM Time tm
WHERE tm.clientid = c.id AND MONTH(`date`) = '$month' AND YEAR(`date`) ='$year'
This is the query to select the times for a user , here by my logic this might be transformed with GROUP BY c.id (client id), and the problem is that it have to contains another WHERE clause which will specify the USER which is unknown. If the users was known value was for example 5, there is no problem to make 5 subsequent for each user WHERE u.id = 1, 2, 3 etc.
So here are the 2 major problems how to display in same query The users header and them select the sum of hours for each client corresponding the user.
Check out the result table hope to make the things clear.
Any suggestion or answer which can come to resolve this situation will be very helpful.
Thank you!

How to fetch items based on inserted order in DynamoDB..?

I have message table in dynamodb with the following fields:
Primary partition key => conversation_id
Primary sort key => id
other attributes => message,date_time,sender_id
+------------------+----------+----------------------+------------------------+----------+
| conversation_id | id | message | date_time | sender_id|
+----------------------------------------------------+------------------------+----------+
| p1OS9E | S04Ln | Hi.. how are you..? | 2016-11-30 06:58:11 pm | 11 |
| p1OS9E | JZkSo | Work finished..? | 2016-11-30 06:58:13 pm | 11 |
| p1OS9E | EN9N4 | I am fine. | 2016-11-30 06:58:12 pm | 12 |
| | | | | |
| a0zgOO | jmDdm | In online..? | 2016-12-40 08:43:12 pm | 51 |
| a0zgOO | mAEdY | Yes.. say.. | 2016-12-40 08:43:14 pm | 34 |
| a0zgOO | aWKrp | Come to play.. | 2016-12-40 08:43:12 pm | 51 |
+------------------+----------+----------------------+------------------------+----------+
While query items based on partition key, the result returned as unordered(not in inserted order).
The sort key id, AttributeType is `string', a random generated code to make the Primary key as unique.
First i used date_time as sort key, but if within same conversation_id with same date_time a message will enter. So the data loss may occur.
How to get my items with the order the message get inserted(based on time)..?
Note: I am using PHP (Codeigniter MVC).
There are many ways you can achieve this, the following are the two approaches that I generally use:
1) Add indexes: You need to add LSI(local secondary index) to your table with range key as DateTime.
Now you can query you LSI by passing you hash key and for DateTime you can use >= or >= operators to get in sorted order.
2) Sorting at application level: I personally use this solution as we don't have to pay additional amount for index, Get all data based on Hash then sort manually at application level by DateTime
There is one more answer of mine with a similar issue.
Hope that helps

MYSQL: Get next 'n' results

Right now I have a PHP script that is fetching the first three results from a MYSQL database using:
SELECT * FROM table Order by DATE DESC LIMIT 3;
After that command I wanted PHP to fetch the next three results, initially I was going to use:
SELECT * FROM table Order by DATE DESC LIMIT 3,3;
However there will be a delay between the two commands which means that it is very possible that a new row will be inserted into the table during the delay. My first thought was to store the DATE value of the last result and then include a WHERE DATE > $stored_date but if entry 3 and 4 have the same date it will skip entry 4 and return results from 5 onward. This could be avoided using the primary key field which is an integer which increments automatically.
I am not sure which the best approach is, but I feel like there should be a more elegant and robust solution to this problem, however I am struggling to think of it.
Example table:
-------------------------------------------
| PrimaryKey | Data | Date |
-------------------------------------------
| 0 | abc | 2014-06-17 11:43:00 |
| 1 | def | 2014-06-17 12:43:00 |
| 2 | ghi | 2014-06-17 13:43:00 |
| 3 | jkl | 2014-06-17 13:56:00 |
| 4 | mno | 2014-06-17 14:23:00 |
| 5 | pqr | 2014-06-17 14:43:00 |
| 6 | stu | 2014-06-17 15:43:00 |
-------------------------------------------
Where Data is the column that I want.
Best will be using primary key and select like
SELECT * FROM table WHERE pk < $stored_pk Order by DATE DESC LIMIT 3;
And if you have automatically generated PK you should use ORDER BY pk it will be faster
Two options I can think of depending on what your script does:
You could either use transactions: performing these queries inside a transaction will give you a consistent view of the data.
Alternatively you could just use:
SELECT * FROM table Order by DATE DESC;
And only fetch the results as you need them.

Datatables Serverside Processing with Column Filterting using Multiple Tables

I'm displaying a record set using Datatables pulling records from two tables.
Table A
sno | item_id | start_date | end_date | created_on |
===========================================================
10523563 | 2 | 2013-10-24 | 2013-10-27 | 2013-01-22 |
10535677 | 25 | 2013-11-18 | 2013-11-29 | 2013-01-22 |
10587723 | 11 | 2013-05-04 | 2013-05-24 | 2013-01-22 |
10598734 | 5 | 2013-06-14 | 2013-06-22 | 2013-01-22 |
Table B
id | item_name |
=====================================
2 | Timesheet testing |
25 | Vigour |
11 | Fabwash |
5 | Cruise |
Now since the number of records returned is going to turn into a big number in near future, I want the processing to be done serverside. I've successfully managed to achieve that but it came at a cost. I'm running into a problem while dealing with filters.
From the figure above, (1) is the column whose value will be in int (item_id), but using some small modifications inside the while loop of the mysql resource, I'm displaying the corresponding string using Table B.
Now if I use the filter (2), it is working fine since those values come from Table A
The Problem
When I try to filter from the field (3), if I enter a string value such as fab it says no record found. But if I enter an int such as 11 I get a single row which contains Fabwash as the item name.
So while filtering I'm required to use the direct value used in Table A and not its corresponding string value stored in Table B. I hope the point that I'm putting across is understandable because it is hard to explain it in words.
I'm clueless on how to solve the issue.

Categories