Good day
I've been struggling trying to make a query... maybe it is impossible to do it in a simple query... maybe not... that's why after several days I come to your help.
I have 7 joined tables, but for simplicity, let's say they are only 2
TblDeffects
------
Date IdOperation Deffects
2013-12-12 1 1
2013-12-12 2 1
2013-12-11 1 1
2013-12-11 3 1
2013-11-10 1 1
2013-11-09 5 1
TblOperations
------
Id Description
1 Operation 1
2 Operation 2
3 Operation 3
4 Operation 4
5 Operation 5
Now, supposing that Deffects lists is longer I want to join both tables, separating them by week (starting on friday and ending on thursday)
I can do that... I think...
But I also want to get ALL operations from the Operations table for each day...
so I could get something like
Output
------
StartDate IdOperation Deffects Description
2013-12-06 1 2 Operation 1
2013-12-06 2 1 Operation 2
2013-12-06 3 1 Operation 3
2013-12-06 4 0 Operation 4 <- No deffects for this
2013-12-06 5 0 Operation 5 <- No deffects for this
2013-11-08 1 1 Operation 1
2013-11-08 2 0 Operation 2 <- No deffects for this
2013-11-08 3 0 Operation 3 <- No deffects for this
2013-11-08 4 0 Operation 4 <- No deffects for this
2013-11-08 5 1 Operation 5
And if possible to get the missing weeks with a 0 in the deffects column...
(The empty row is just to separate the months and make it a little easier to read here)
Right now what I get are both joined tables and at the end the operation that wasn't included (in this case Operation #4 with a NULL date)
Is it possible to create a query like that??
Thank you
If you do not want to depend on the Deffects table being populated with data, you need a temporary table containing the dates you want to check. The only way to get this, is a loop unfortunately.
DECLARE #dates TABLE(Date DATETIME NOT NULL UNIQUE)
DECLARE #firstDate DATETIME = '2013-11-08T00:00:00Z'
DECLARE #weeks INT = 7
DECLARE #currentWeek INT = 0
WHILE (#currentWeek < #weeks) BEGIN
INSERT #dates VALUES (DATEADD(DAY, #currentWeek * 7, #firstDate))
SET #currentWeek = #currentWeek + 1
END
SELECT Dates.Date, Operations.Id IdOperation, (SELECT COUNT(*) FROM Defects WHERE Defects.date_inspected >= Dates.Date AND Defects.date_inspected < DATEADD(DAY, 7, Dates.Date) AND Defects.id_operation = Operations.Id) AS Deffects, Operations.Description
FROM #dates Dates
CROSS JOIN Operations
ORDER BY Dates.Date DESC
SqlFiddle for this: http://sqlfiddle.com/#!3/3142db/25
EDIT: Adjusted code to match the sqlFiddle provided.
Related
I'm trying to update my main table by comparing it with another table that contains the same fields but have the daily values. The second table contains multiple records for same person too. (no primary key in this table)
My query executes fine but it stops when it finds the first match and doesn't scan rest of the table.
update crates as a, t23042019 as b set a.srsb=a.srsb+b.srsb, a.srsc=a.srsc+b.srsc, a.hfc=a.hfc+b.hfc, a.mix=a.mix+b.mix where a.name=b.name;
crates table
name srsb srsc hfc mix
hitesh 5 5 5 5
raman 2 3 4 1
t23042019 table
name srsb srsc hfc mix
raman 1 -2 0 1
hitesh 2 2 2 2
hitesh -5 0 0 -2
raman -1 0 0 0
Expected result after the query
crates table
name srsb srsc hfc mix
hitesh 2 7 7 5
raman 2 1 4 2
Query result
crates table
name srsb srsc hfc mix
hitesh 7 7 7 7
raman 3 1 4 2
Something like below:
UPDATE crates a
INNER JOIN (
SELECT name, SUM(srsb) AS srsb, SUM(srsc) AS srsc, SUM(hfc) AS hfc, SUM(mix) AS mix
FROM t23042019
GROUP BY name) s
ON a.name=s.name
SET a.srsb=a.srsb+s.srsb,
...
I need to count records created since it was last 9:00am.
so at 8:59am I need to count all records since yesterday at 9:00am and at 9:01am I will need to count since today at 9:00am,
data sample
ID | created
----------------------------------
1 | 2018-11-13 17:00
2 | 2018-11-13 09:00
3 | 2018-11-13 08:01
4 | 2018-11-12 13:00
5 | 2018-11-11 17:31
running the query at 13-11-2018 8:59am should return 2 (rows 3,4)
running the query at 13-11-2018 9:01am should return 1 (rows 2)
the query I'm looking for should be something like:
SELECT count(id) FROM myTable WHERE created > "TIME_SINCE_9AM()"
any help?
I figured out a solution, I hoped for a prettier query but it works...
I'm using IF statement to determine if right now is before 9am or after and running count on records accordingly, (the H var is for testing purposes, if you put 18 in there it works since last 18:00)
SET #H = "9";
SELECT
IF (TIMEDIFF(NOW(), SUBDATE(CURDATE(),INTERVAL (-#H) HOUR))<0,
SUM(CASE WHEN created>SUBDATE(CURDATE(),INTERVAL (-#H+24) HOUR) THEN 1 ELSE 0 END),
SUM(CASE WHEN created>SUBDATE(CURDATE(),INTERVAL (-#H) HOUR) THEN 1 ELSE 0 END)
) counter
FROM mytable
The mysql table we work on has data in the following format:
entityId status updated_date
-------------------------------
1 1 29/05/2017 12:00
1 2 29/05/2017 03:00
1 3 29/05/2017 07:00
1 4 29/05/2017 14:00
1 5 30/05/2017 02:00
1 6 30/05/2017 08:00
2 1 31/05/2017 03:00
2 2 31/05/2017 05:00
.
.
So every entity id has 6 statuses, and every status has an update datetime. Each status has an activity attached to it.
For example 1 - Started journey
2 - Reached first destination
3 - Left Point A, moving towards B. etc
I need to get an output in the below format for specific entity id eg 3 and 4. I need the time for status 3 and 4 independently.
entity_id time_started_journey time_reached_first_destination
(update time of status 3) (update time of status 4)
--------------------------------------------------------------
1 29/05/2017 7:00 29/05/2017 14:00
2 30/05/2017 7:00 30/05/2017 16:00
Later I need to calculate the total time which would be the difference of the two.
How can I achieve the desired result using mysql.
I tried using Union operator but cannot do it separate columns.
Also, tried using case when operator with the below query but failed.
select distinct entityid,
(case status when 3 then freight_update_time else 0 end)
as starttime,
(case status when 4 then freight_update_time else 0 end) as endtime
from table ;
Can anyone throw light on this?
Conditional aggregation is one way to return a resultset that looks like that.
SELECT t.entityid
, MAX(IF(t.status=3,t.updated_date,NULL)) AS time_started_journey
, MAX(IF(t.status-4,t.updated_date,NULL)) AS time_reached_first_destination
FROM mytable t
WHERE t.status IN (3,4)
GROUP BY t.entityid
ORDER BY t.entityid
This is just one suggestion; the specification is unclear about what the query should do with duplicated status values for a given entityid.
There are other query patterns that will return similar results.
My query in MySQL
SELECT
e3.updated_date AS sta3,
e4.updated_date AS sta4
FROM
`prueba` AS e3
LEFT JOIN prueba AS e4
ON
e3.entityId = e4.entityId AND e4.status = 4
WHERE
e3.status = 3
OUTPUT:
Have a existing table of results like this;
race_id race_num racer_id place
1 0 32 2
1 1 32 3
1 2 32 1
1 3 32 6
1 0 44 2
1 1 44 2
1 2 44 2
1 3 44 2
etc...
Have lots of PHP scripts that access this table output the results in a nice format.
Now I have a case where I need to output the results for only certain race_nums.
So I have created this table races_included.
race_view race_id race_num
Day 1 1 0
Day 1 1 1
Day 2 1 2
Day 2 1 3
And can use this query to get the right results.
SELECT racer_id, place from results WHERE race_id=1
AND race_num IN
(SELECT race_num FROM races_included WHERE race_id='1' AND race_view='Day 1')
This is great but I only need this feature for a few races and to have it work in a compatible mode for the simple case show all races. I need to add alot of rows to the races_included table. Like
race_view race_id race_num
All 1 0
All 1 1
All 1 2
All 1 3
95% of my races don't use the daily feature.
So I am looking for a way to change the query so that if for race 1 there are no records in the races_included table it defaults to all races. In addition I need it to be close the same execution speed as the query without the IN clause, because this query Or variations of it are used a lot.
One way that does work is to redefine the table as races_excluded and use NOT IN. This works great but is a pain to manage the table when races are added or deleted.
Is there a simple way to use EXISTS and IN in tandem as a subquery to get the desired results? Or some other neat trick I am missing.
To clarify I have found a working but very slow solution.
SELECT * FROM race_results WHERE race_id=1
AND FIND_IN_SET(race_num, (SELECT IF((SELECT Count(*) FROM races_excluded
WHERE rid=1>0),(SELECT GROUP_CONCAT(rnum) FROM races_excluded
WHERE rid=1 AND race_view='Day 1' GROUP BY rid),race_num)))
It basically checks if any records exists for that race_id and if not return a set equal to the current race_num and if yes returns a list of included race nums.
You can do this by using or in the subquery:
SELECT racer_id, plac
from results
WHERE race_id = 1 AND
race_num IN (SELECT race_num
FROM races_included
WHERE race_id = '1' AND (race_view = 'Day 1' or raw_view = 'ANY')
);
Problem: I’m going to explain this problem using the Sakila sample database and it data so it is easier for you. Ok, so my question is how can I compare the current record to the next in the same table in terms of 'datetime'. This is how the table looks like:
payment_id customer_id staff_id rental_id amount payment_date last_update
1 1 1 76 2.99 25/05/2005 11:30:37 15/02/2006 22:12:30
2 1 1 573 0.99 28/05/2005 10:35:23 15/02/2006 22:12:30
3 1 1 1185 5.99 15/06/2005 00:54:12 15/02/2006 22:12:30
4 1 2 1422 0.99 15/06/2005 18:02:53 15/02/2006 22:12:30
5 1 2 1476 9.99 15/06/2005 21:08:46 15/02/2006 22:12:30
Using the above explanation in this sample, for each ‘staff_id’, how can I compare the current row with the next (using ‘payment_date’ for current and next), so it brings only the pair of records where the amount of the current record is the same as the next (something like current.amount = next.amount). This means that each record should be compared to the next of the same ‘staff_id’, and so on.
I’m currently using this query, which do the job, but it takes for ever. I know it works good because I setted LIMIT 3 and it brought the correct ones (you can test it as well if you have the Sakila sample database):
SELECT * FROM payment a
JOIN payment b ON a.staff_id = b.staff_id AND a.payment_date > b.payment_date AND a.amount = b.amount
LEFT JOIN payment c ON a.staff_id = c.staff_id AND c.payment_date < a.payment_date AND c.payment_date > b.payment_date
WHERE c.payment_id IS NULL
LIMIT 3;
Could you please help me?