How to identify entries that have not changed over time? - mysql

I am trying to identify names that have not had a total score change over a period of time, and what that period of time was.
Example Table:
+----------+--------+-------+
| Date | Name | Score |
+----------+--------+-------+
| 1/1/2016 | Frank | 55 |
| 1/1/2016 | John | 80 |
| 1/2/2016 | Frank | 60 |
| 1/2/2016 | John | 85 |
| 1/3/2016 | Frank | 60 |
| 1/3/2016 | John | 100 |
| 1/4/2016 | Frank | 60 |
| 1/4/2016 | John | 120 |
| 1/5/2016 | Frank | 60 |
| 1/5/2016 | John | 120 |
+----------+--------+-------+
Expected Output:
+-------+------+
| Name | Days |
+-------+------+
| Frank | 4 |
| John | 2 |
+-------+------+
I have been trying to puzzle out how to do this with no success. I have no code to show since none of it has even been close to successful and would only serve to clutter up the question.
How can I go about doing this?

You need to group the data with the score, and then calculate the first and last day that the user has that score, check this:
SELECT DATEDIFF(last_day, first_day) + 1 AS days, name, score,
first_day, last_day
FROM (
SELECT
max(date_score) as last_day,
min(date_score) as first_day,
score,
name
FROM members
GROUP by score
) AS score
The Date diff function return the difference between two DATE's, we add one to represent that the score last one day.
Check here for a working example link

Related

how to query sum for one field of two mysql tables

I have two mysql table.
Table: bill
id | billtype | amount | advid | paydate |adjid | adjdate |
1 | electric | 10000 | 123 | 2017-01-01 | 50 | 2017-01-03 |
2 | Water | 5000 | 124 | 2017-02-01 | 0 | 0000-00-00 |
3 | Shirt | 500 | 125 | 2017-03-01 | 0 | 0000-00-00 |
Table: advance
id | advid | amount | balance | purpose |
1 | 123 | 50000 | 20000 | Bill |
2 | 124 | 70000 | 10000 | Bill |
3 | 125 | 55000 | 15000 | Uniform |
4 | 124 | 60000 | 10000 | Bill |
I want to create a drop down menu so that to select those 'advance' which are not adjusted yet (adjid=0 and adjdate=0000-00-00) in Table: bill and that drop down menu will also contain the total value of advance for same advance id (advid) like below:
<option>Bill-130000</option>
<option>Uniform-55000</option>
As total 130000 (70000+60000) advance is taken against advance id 124, so the Total amount of Advance in Option menu should be 130000 in case of Bill. But I am failed to calculate total amount of advance accurately:
SELECT sum(a.amount), purpose FROM bill as b, advance as a WHERE b.paydate!='0000-00-00' AND b.adjid!=0 AND a.advid=b.advid GROUP BY a.advid
Total amount in <option></option> is not coming actual.
What would be the right query for this purpose?
You could try
SELECT SUM(a.amount) AS amount,
MAX(purpose) AS purpose
FROM advance a
WHERE a.advid IN (
SELECT b.advid
FROM bill b
WHERE b.paydate = '0000-00-00'
AND b.adjid = 0)
GROUP BY a.advid

MySQL select a row from a daterange excluding the year

I'm trying to create a MySQL query to select the daily price from a table that is between a date range from another. I only want to use 'starting-ending' months and days from the table "seasons" and I want to pass the year dynamically to the query.
This is my query: (I'm giving it the Year to exclude the one on the table)
SELECT a.season, b.base_price
FROM seasons a
JOIN pricebyseason b ON a.id=b.season_id
WHERE b.prop_id='6' AND '2015-11-29' BETWEEN DATE_FORMAT(a.starting,'2015-%m-%d') AND DATE_FORMAT(a.ending,'2016-%m-%d')
ORDER BY b.base_price DESC
It works but not with all dates.
These are the tables:
seasons (these are static date values)
+----+--------------+------------+------------+
| id | season | starting | ending |
+----+--------------+------------+------------+
| 1 | Peak Season | 2015-12-11 | 2016-01-09 |
| 2 | High Season | 2015-11-27 | 2016-04-15 |
| 3 | Mid Season | 2015-04-16 | 2015-09-01 |
| 4 | Low Season | 2015-09-02 | 2015-11-26 |
| 5 | Spring Break | 2015-03-05 | 2015-03-21 |
+----+--------------+------------+------------+
pricebyseason
+----+---------+-----------+------------+
| id | prop_id | season_id | base_price |
+----+---------+-----------+------------+
| 1 | 6 | 1 | 950 |
| 2 | 6 | 2 | 750 |
| 3 | 6 | 3 | 450 |
| 4 | 6 | 4 | 400 |
| 5 | 6 | 5 | 760 |
+----+---------+-----------+------------+
What I want to achive is query the dialy price between checkin, checkout selection
I create this sqlfiddle: http://sqlfiddle.com/#!9/4a6f4
This is a previuos query that is not working either:
SELECT a.base_price,b.season,b.starting,b.ending
FROM pricebyseason a JOIN seasons b ON a.season_id=b.id
WHERE a.prop_id='6' AND
(DATE_FORMAT(b.starting,'%m-%d') <= '12-27' OR DATE_FORMAT(b.starting,'2016-%m-%d') >= '2015-12-27')
AND
(DATE_FORMAT(b.ending,'%m-%d') >= '12-27' OR DATE_FORMAT(b.ending,'2016-%m-%d') <= '2015-12-27')
ORDER BY base_price DESC
And here are some sample dates for each season: '2016-01-08','2015-12-27','2016-04-14','2015-11-29','2016-04-15','2015-09-01','2016-09-02','2015-11-26','2016-10-10','2016-03-18','2016-06-22','2015-06-15'
Thank a lot

Remove duplicates SQL while ignoring key and selecting max of specified column

I have the following sample data:
| key_id | name | name_id | data_id |
+--------+-------+---------+---------+
| 1 | jim | 23 | 098 |
| 2 | joe | 24 | 098 |
| 3 | john | 25 | 098 |
| 4 | jack | 26 | 098 |
| 5 | jim | 23 | 091 |
| 6 | jim | 23 | 090 |
I have tried this query:
INSERT INTO temp_table
SELECT
DISTINCT #key_id,
name,
name_id,
#data_id FROM table1,
I am trying to dedupe a table by all fields in a row.
My desired output:
| key_id | name | name_id | data_id |
+--------+-------+---------+---------+
| 1 | jim | 23 | 098 |
| 2 | joe | 24 | 098 |
| 3 | john | 25 | 098 |
| 4 | jack | 26 | 098 |
What I'm actually getting:
| key_id | name | name_id | data_id |
+--------+-------+---------+----------+
| 1 | jim | 23 | NULL |
| 2 | joe | 24 | NULL |
| 3 | john | 25 | NULL |
| 4 | jack | 26 | NULL |
I am able to dedupe the table, but I am setting the 'data_Id' value to NULL by attempting to override the field with '#'
Is there anyway to select distinct on all fields and while keeping the value for 'data_id'? I will take the highest or MAX data_id # if possible.
If you only want one row returned for a specific value (in this case, name), one option you have is to group by that value. This seems like a good approach because you also said you wanted the largest data_id for each name, so I would suggest grouping and using the MAX() aggregate function like this:
SELECT name, name_id, MAX(data_id) AS data_id
FROM myTable
GROUP BY name, name_id;
The only thing you should be aware of is the possibility that a name occurs multiple times under different name_ids. If that is possible in your table, you could group by the name_id too, which is what I did.
Since you stated you're not interested in the key_id but only the name, I just excluded it from the query altogether to get this:
| name | name_id | data_id |
+-------+---------+---------+
| jim | 23 | 098 |
| joe | 24 | 098 |
| john | 25 | 098 |
| jack | 26 | 098 |
Here is the SQL Fiddle example.
RENAME TABLE myTable to Old_mytable,
myTable2 to myTable
INSERT INTO myTable
SELECT *
FROM Old_myTable
GROUP BY name, name_id;
This groups my tables by the values I want to dedupe while still keeping structure and ignoring the 'Data_id' column

Mysql how to find cumulative total by group

Can anyone help me to sort this out pleaase. i have a episode table and for an episode there will be following appointments . Episode table will be like
+-------------+------------+------------+------------+----------------+------+
| Episode_id | Patientid | St_date | End_date | Status | ... |
+-------------+------------+------------+------------+----------------+------+
| 61112345 | 100001 | 12-01-2010 | | Active | |
| 61112346 | xxxxxx | 20-01-2010 | 10-10-2011 | Withdrawn | |
| ......... | xxxxxxxx | 30-01-2010 | 10-05-2011 | Lost to follow | |
| ......... | xxxxxxxx | 01-02-2011 | Active | Active | |
+-------------+------------+------------+------------+----------------+------+
Status field holds the status of each episode.A episode has 6 appointments , 3 months per appointment. so totally an episode has 18 months . some patient may complete all 6 appointment , some may withdraw in the middle, or some will be lost to follow up. i need to create a dashboard .
Appointment table will have fields for
Appointment_id
PatientId
...
Stats // Completed or pending, which is used for reporting
For example if a patient complete 2 appointment and if he is marked as Withdrawn on episdode which means that he has withdrawn from 3rd visit and active for 2 visits, if we lost to follow him on 5th app, then he will be active for 4app and then he will be added to lost to follow up on 5th visit. if he completes all then he will added to active for all 6 visits. and the report should be like
Report from 01-01-2010 to 31-12-2010
+--------+--------+-------------+----------------+---------+
| | Active | Withdrawn | Lost to follow | Revised |
+------- +--------+-------------+----------------+---------+
| visit1 | 1500 | 30 | 5 | 5 |
| Visit2 | 1800 | 20 | 4 | 3 |
| Visit3 | 1900 | 45 | 3 | 2 |
| Visit4 | 1800 | 34 | 0 | 1 |
| Visit5 | 1900 | 30 | 0 | 1 |
| Visit6 | 1200 | 20 | 0 | 5 |
+--------+--------+-------------+----------------+---------+
Currently we are fetching the query and using loop only we are generating reports like this, but it is taking time to process, is there any way i can achieve using query itself.
It isn't really clear what you want to group by, but I can give you a general answer. After your where clause you can add "group by fieldname order by fieldname" where fieldname is the element you want to count or sum. You can then count(fieldname) or sum(fieldname) to either add or count.
This may be helpful: http://www.artfulsoftware.com/infotree/qrytip.php?id=105

Group column values together in one cell

I need to write an SQL select statement that groups together values from one column into one cell.
e.g.
table name: Customer_Hobbies
+------------+------------+-----------+
| CustomerId | Age | Hobby |
+------------+------------+-----------+
| 123 | 17 | Golf |
| 123 | 17 | Football |
| 324 | 14 | Rugby |
| 627 | 28 | Football |
+------------+------------+-----------+
should return...
+------------+------------+----------------+
| CustomerId | Age | Hobbies |
+------------+------------+----------------+
| 123 | 17 | Golf,Football |
| 324 | 14 | Rugby |
| 627 | 28 | Football |
+------------+------------+----------------+
Is this possible?
N.B. I know the data's not laid out in a particularly sensible way, but I can't change that.
You want group_concat():
select customerId, age, group_concat(hobby) as hobbies
from t
group by customerId, age