mysql - query to lookup multiple records - mysql

I have a single mysql table. Query should lookup prev_id multiple times till the insertimestamp is between cuurent and previous week and get the rows to columns.
ID | inserttimestamp| prev_id | category
-----------------------------
5 | 2017-06-08 | 4 | Level456
4 | 2017-06-05 | 3 | Level241
3 | 2017-05-31 | 2 | Level456
2 | 2017-05-28 | 1 | Level247
1 | 2017-05-27 | | Level231
The result should be something like this,
ID | inserttimestamp| prev_id | category | id1 | id1_category | id2 | id2_category |
--------------------------------------------------------------------------------------------
5 | 2017-06-08 | 4 | Level456 | 4 | Level 241 | 3 | Level456 |
In this case as you see it stopped to id 3 because id 2 and 1 are not falling under previous week.
Use Case: To find out how many level upgrade/downgrade happened since previous week
For the above records its Levelupgrade - 1 , LevelDowngrade -1
Any help would be highly appreciated. Thanks in advance.

Related

MySQL timestampdiff of records on same column

I have a table in which I am trying to sum times on the same column. I have a column where I log all time entries of any event. So, I would like to group them by gateway ID and have the value in hours, minutes and seconds. I have tried to used timestampdiff, but it takes three arguments and since I have only one row, I couldn't find a way. Is that possible? My table looks like this:
+----+---------+---------------------+
| id | gateway | timestamp |
+----+---------+---------------------+
| 1 | 1 | 2018-03-21 08:52:51 |
| 2 | 1 | 2018-03-21 08:52:54 |
| 3 | 1 | 2018-03-21 08:52:58 |
| 4 | 1 | 2018-03-21 08:53:11 |
| 5 | 2 | 2018-03-21 08:53:51 |
| 6 | 1 | 2018-03-21 08:54:21 |
| 7 | 2 | 2018-03-21 08:54:32 |
| 8 | 2 | 2018-03-21 08:54:44 |
| 9 | 2 | 2018-03-21 08:54:53 |
| 10 | 2 | 2018-03-21 08:55:01 |
+----+---------+---------------------+
basically I would like to group all records by their gateway and then have the sum of time there.
Thanks in advance!
I think you want:
select gateway,
timestampdiff(seconds, min(timestamp), max(timestamp))
from t
group by gateway;
I'm a little confused by your question, because timestampdiff() takes three arguments, not two.

Update records based on date on MySQL using joins

I have all those tables above.
car_model_tbl
-----------------------------
id | car_model_name|status |
-----------------------------
1 | seria_1 | 1 |
-----------------------------
2 | golf_4 | 1 |
-----------------------------
3 | C_Class | 1 |
-----------------------------
4 | golf_5 | 1 |
-----------------------------
5 | seria_2 | 0 |
-----------------------------
car_manufacturer_tbl
-------------------------
id |car_manufactu_name |
-------------------------
1 | bmw |
-------------------------
2 | volkswagen |
-------------------------
3 | mercedes |
-------------------------
car_service_tbl
---------------------------------
id | model_id| service_date |
---------------------------------
1 | 1 | 2018-03-10 |
---------------------------------
2 | 2 | 2018-02-10 |
---------------------------------
3 | 1 | 2018-01-10 |
---------------------------------
4 | 1 | 2017-12-10 |
---------------------------------
5 | 2 | 2017-12-10 |
---------------------------------
6 | 3 | 2018-02-10 |
---------------------------------
7 | 2 | 2018-01-10 |
---------------------------------
9 | 4 | 2018-03-10 |
---------------------------------
10 | 4 | 2018-02-10 |
---------------------------------
11 | 5 | 2018-02-10 |
---------------------------------
car_model_manufacturer_relation
-------------------------------------------------
id | model_id | manufactu_id| service_status |
-------------------------------------------------
1 | 1 | 1 | 1 |
-------------------------------------------------
2 | 5 | 1 | 1 |
-------------------------------------------------
3 | 2 | 2 | 1 |
-------------------------------------------------
4 | 4 | 1 | 1 |
-------------------------------------------------
5 | 2 | 2 | 1 |
-------------------------------------------------
6 | 3 | 3 | 1 |
-------------------------------------------------
I need to update car_model_manufacturer_relation.service_status = '0'
where car_service_tbl.service_date < "2018-03-01".
In this case car_model_manufacturer_relation.service_status of models 2, 3 and 5 should be set to '0' because every car_service_tbl.service_date for these models is smaller than "2018-03-01".
However, for models 1 and 4 car_model_manufacturer_relation.service_status should stay '1' because even that they have records smaller than "2018-03-01" they also have bigger dates ex. "2018-03-10".
I am trying to create a query for this but until now without success.
You'll need to nest a grouped query, to get the MAX date per model, and update from that.
update car_model_manufacturer_relation as cmmr,
(select model_id, max(service_date) as check_date
from car_service_tbl
group by model_id) as cst
set cmmr.service_status = '0'
where cmmr.model_id = cst.model_id
and cst.check_date < "2018-03-01"
Where you're using more than one table and the table names include underscores, I try and alias the tables to make the code a little shorter and easier on the eye, hence the use of cmmr and cst as table aliases.
The MAX date has also been renamed for clarity as check_date. You can of course name this anything you wish.
With sub query:
UPDATE car_model_manufacturer_relation c
LEFT join (SELECT model_id, service_date FROM car_service_tbl ORDER BY service_date DESC LIMIT 1) as s ON s.model_id = c.model_id
SET service_status=0
WHERE c.service_date < "2018-03-01"
#tyro - be careful with your solution, as a LEFT JOIN would update the service status to 0 when there wasn't a service date within the car_service_tbl. You would need to use a full join, rather than just the LEFT JOIN as you suggested in order to update the records correctly I feel.

MS Access - display repeating rows once with the highest value

I have 2 tables in MS Access with the following values
Customer
id | name
1 | jon
2 | bob
3 | jack
Order
id | amount | date | customer
5 | 50 | 3/10/2017 | 1
4 | 100 | 3/10/2017 | 1
3 | 45 | 2/28/2017 | 2
2 | 10 | 3/10/2017 | 3
1 | 5 | 3/10/2017 | 2
I want to get an output of
name | orderid | amount
jon | 5 | 50
bob | 3 | 45
jack | 2 | 10
I want to get amount of the latest order id per customer, however I keep getting this
name | orderid | amount
jon | 5 | 50
jon | 4 | 100
bob | 3 | 45
bob | 2 | 10
jack | 1 | 5
I used the query designer and have used the function MAX() to the order id, GROUP BY to all columns (MS Access does not allow to group the rows using a single column), DISTINCT and DISTINCTROW, as well as set the query properties "Unique Records" to Yes but the duplicate records still shows.

Need help/explanation to JOINED query

I'm kinda lost on what kind of SQL query I should do to achieve what I want.
Let's say I have three tables :
select * FROM trip;
| trip_id | title | description
----------------------------------
| 1 | title1 | desc1 |
| 2 | title2 | desc2 |
| 3 | title3 | desc3 |
| 4 | title4 | desc4 |
| 5 | title5 | desc5 |
| 6 | title6 | desc6 |
select * FROM weekly_report;
| report_id | trip_id| incident_id
----------------------------------
| 1 | 1 | (null) |
| 2 | 1 | (null) |
| 3 | 1 | 1 |
| 4 | 2 | 2 |
| 5 | 3 | 3 |
| 6 | 3 | (null) |
select * FROM incident;
| incident_id | error_code |
----------------------------------
| 1 | 22223 |
| 2 | 25456 |
| 3 | 25456 |
So for a little operationnal knowledge :
The trip table contains 1 record PER trip done by the customer.
The weekly_report contains A report per Week of the trip. (1 trip of 2 weeks will have 2 records, 1 trip or 5 weeks will have 5.. ).
The incident table contains 1 record per incident. (If an incident happened during a week : we create a record in the incident table, else we do nothing)
I'd like to find in a single query (or if it has to be, with subqueries) the number of trips where during at least a week there has been an incident declared for the error_code "25456".
Expected result from the sample data : 2 ( because for trip 2 and three there exist an incident with the error code 25456 ).
I can explain more if needed, is there anybody out there willing to help me ?
Thanks,
You need to take count of distinct trips for related incidents
select count(distinct w.trip_id)
from weekly_report w
inner join incident i
on w.incident_id = i.incident_id
where i.error_code = 25456;
Try this:
SELECT w.trip_id
FROM incident i
INNER JOIN weekly_report w ON i.incident_id=w.incident_id
WHERE error_code='25456'
and if you want the count,then
SELECT COUNT(w.trip_id)
FROM incident i
INNER JOIN weekly_report w ON i.incident_id=w.incident_id
WHERE error_code='25456'

What happens if I select two tables with no WHERE clause?

I had a technical interview last week, and my interviewer asked me what happens if I run the following query:
SELECT * FROM tbl1, tbl2
I think I answered it correctly, but it wasn't an in-depth answer.
I said that I would select all the columns in both tables. For example if tbl1 has 3 columns, and tbl2 has 4 columns. The result set would have 7 columns.
Then he asked me why 7? and I said because I was selecting everything from each table.
That was a bad answer, but I couldn't think of anything else.
To cut to the chase, after the interviewed I executed the latter statement using two tables.
Table A, had 3 animal: dog, cat and elephant.
Table B had 2 names: Mat and Beth
This is the result set that I got after the statement being executed:
*********************************************
| id_tbl1 | name_tbl1 | id_tbl2 | name_tbl2 |
*********************************************
| 1 | dog | 1 | Mat |
| 2 | cat | 1 | Mat |
| 3 | elephant | 1 | Mat |
| 1 | dog | 2 | Beth |
| 2 | cat | 2 | Beth |
| 3 | elephant | 2 | Beth |
*********************************************
So my question is, why does the statement behaves like that?
In other words:
Why does the Table B's records repeat themselves until I reach the end of table A, and then it starts all over again?
How would you have answered the question in a way that it would've "WOW'd" the interviewer?
If this question does not belong to SO, feel free to delete it or close it!
If you do a select like this, all rows in one resultset are joined to all rows in the other resultset (Cartesian Product).
So you get a list of all rows of the first table with the first row of the second table, Then all entries for the second row and so on. The order may be an implementation detail. Not sure if it is defined that the first order is by the first table, it might be different across implementations.
If you join three tables (or more), then the same happens with all rows of all tables. This, of course, is not only for tables, but for any result set from joins.
The result will be a cartisian product
take a look at this example
SQL Example
You can see there are two tables one has 5 records and the other has 4 and the result is 20 records. Means 5 * 4 = 20 instead of 5 + 4 = 9 as you are assuming.
Table1
| IDX | VAL |
---------------
| 1 | 1val1 |
| 1 | 1val2 |
| 2 | 2val1 |
| 2 | 2val2 |
| 2 | 2val3 |
Table2
| ID | POINTS |
---------------
| 1 | 2 |
| 2 | 10 |
| 3 | 21 |
| 4 | 29 |
Result of below query
SELECT * FROM Table1 , Table2
| IDX | VAL | ID | POINTS |
-----------------------------
| 1 | 1val1 | 1 | 2 |
| 1 | 1val1 | 2 | 10 |
| 1 | 1val1 | 3 | 21 |
| 1 | 1val1 | 4 | 29 |
| 1 | 1val2 | 1 | 2 |
| 1 | 1val2 | 2 | 10 |
| 1 | 1val2 | 3 | 21 |
| 1 | 1val2 | 4 | 29 |
| 2 | 2val1 | 1 | 2 |
| 2 | 2val1 | 2 | 10 |
| 2 | 2val1 | 3 | 21 |
| 2 | 2val1 | 4 | 29 |
| 2 | 2val2 | 1 | 2 |
| 2 | 2val2 | 2 | 10 |
| 2 | 2val2 | 3 | 21 |
| 2 | 2val2 | 4 | 29 |
| 2 | 2val3 | 1 | 2 |
| 2 | 2val3 | 2 | 10 |
| 2 | 2val3 | 3 | 21 |
| 2 | 2val3 | 4 | 29 |
I think you are confusing yourself by running an example with two tables that have identical fields. You are referring to a Union, which will combine the values of 1 table with another, and using your example this would give you 3 + 4 = 7 results.
The comma separated FROM statement is doing JOIN, which will go through all values in Table X and pair them with all the values of Table Y. This would result in Size of X * Size of Y results, and using your example this would be 3 * 4 = 12.