Find the sum of DATETIME differences within a table? - mysql

I have the following table:
---------------------------------
| id | class_id | time | status |
---------------------------------
| 1 | 1 | <> | 1 |
---------------------------------
| 2 | 2 | <> | 1 |
---------------------------------
| 3 | 1 | <> | 0 |
---------------------------------
| 4 | 2 | <> | 0 |
---------------------------------
I want a query that will see that the first row has class_id = 1 and status = 1. It will then look for the next row with class_id = 1 and status = 0, and find the time difference between the two (time is DATETIME).
At the end of all this, it will return me a sum of all time differences (i.e. (row 1 - row 3) + (row2 - row4)).
How is this possible? In generalisation, the question is about getting an aggregate total of differences between rows in a table, based off a condition.

For every status 0 record we search the latest status 1 record. This is from all previous status 1 records take the latest.
select
class_id,
sum
(
timestampdiff
(
second,
(
select s1.time
from mytable s1
where s1.status = 1
and s1.class_id = s0.class_id
and s1.id < s0.id
order by s1.id desc limit 1
),
s0.time
)
) as diffsecs
from mytable s0
where status = 0
group by class_id;

Related

SELECT MAX OF COUNT IN PHPMyadmin

I have a problem with SQLcode
I have a table
id | content | id_user | id_store
1 | abc | 1 | 10
2 | xzy | 1 | 10
3 | abc | 1 | 10
4 | abc | 1 | 11
5 | abc | 1 | 12
My problem is how i got the result is the count of max (id_store) which is 2* value >= max(id_store)
This is a example, result will be
id_store | count(...)
10 | 3
because (3*2) > max of count = 3
Tks everyone
It's very difficult to understand your question. Try to use the next query
SELECT id_store,COUNT(*) CountOfStore
FROM `Your Table`
GROUP BY id_store
HAVING 2*COUNT(*) >= (
SELECT MAX(CountOfStore) -- max of all CountOfStore
FROM
(
SELECT COUNT(*) CountOfStore -- count of store for each id_store
FROM `Your Table`
GROUP BY id_store
)
)
Hope I understood you rightly.

MySql: update row that requires some logic processing

Given the following table:
id | company | names | group
-------------------------------------
0 | 1 | John | 1
1 | 1 | Doe | null //populate with preceding group number (i.e. 1)
2 | 1 | Yo | null //populate with preceding group number (i.e. 1)
3 | 1 | Zoe | null //populate with preceding group number (i.e. 1)
4 | 1 | Jack | 2
5 | 1 | Doe | null //populate with preceding group number (i.e. 2)
6 | 1 | Yo | null //populate with preceding group number (i.e. 2)
May I know how i can update only the null values to its preceding group number via sql statements? Thanks.
Try this:
UPDATE tablename t1
JOIN (
SELECT ID, #s:=IF(`group` IS NULL, #s, `group`) `group`
FROM (SELECT * FROM tablename ORDER BY ID) r,
(SELECT #s:=NULL) t
) t2
ON t1.ID = t2.ID
SET t1.`group`= t2.`group`
SQLFIDDLE DEMO

Get ids where all values of a field have a certain value

I have this table
f_id | user_id | sent
==============================
1 | 1 | 0
1 | 2 | 1397820533
1 | 3 | 0
1 | 4 | 1397820533
2 | 1 | 1397820533
2 | 2 | 1397820533
2 | 3 | 1397820533
3 | 1 | 1397820533
3 | 2 | 1397820533
now I would like to have all f_id's where all sent fields have a timestamp ( != 0 )
SELECT * FROM table WHERE sent != 0 GROUP BY f_id
returns all three cause there are some which have a timestamp.
A a result I expect
f_id
=====
2
3
cause f_id still have some 0 values
You are close, but you want to move the condition to the having clause:
SELECT f_id
FROM table
GROUP BY f_id
HAVING SUM(sent = 0) = 0;
The having clause counts the number of rows with sent = 0. The = 0 means there are none of them.
SELECT Distinct f_id
FROM table
WHERE sent >= 0
Try this
SELECT * FROM table
WHERE f_id not in (select f_id from table where sent=0)
GROUP BY f_id
Try this:
select *
from
(SELECT *
FROM table
WHERE sent != 0) tempalias
GROUP BY f_id

how to find duplicates and gaps in this scenario in mysql

Hi I have a table that looks like
-----------------------------------------------------------
| id | group_id | source_id | target_id | sortsequence |
-----------------------------------------------------------
| 2 | 1 | 2 | 4 | 1 |
-----------------------------------------------------------
| 4 | 1 | 20 | 2 | 1 |
-----------------------------------------------------------
| 5 | 1 | 2 | 14 | 1 |
-----------------------------------------------------------
| 7 | 1 | 2 | 7 | 3 |
-----------------------------------------------------------
| 20 | 2 | 20 | 4 | 3 |
-----------------------------------------------------------
| 21 | 2 | 20 | 4 | 1 |
-----------------------------------------------------------
Scenario
There are two scenarios that needs to be handled.
Sortsequence column value should be unique against one source_id and group_id. For example if all the records having group_id = 1 AND source_id = 2 should have sortsequence unique. In above example records having id= and 5 which are having group_id = 1 and source_id = 2 have same sortsequence which is 1. This is faulty record. I need to find out these records.
If group_id and source_id is same. The sortsequence columns value should be continous. There should be no gap. For example in above table records having id = 20, 21 having same group_id and source_id and sortsequence value is 3 and 1. Even this is unique but there is a gap in sortsequence value. I need to also find out these records.
MY So Far Effort
I have written a query
SELECT source_id,`group_id`,GROUP_CONCAT(id) AS children
FROM
table
GROUP BY source_id,
sortsequence,
`group_id`
HAVING COUNT(*) > 1
This query only address the scenario 1. How to handle scenario 2? Is there any way to do it in same query or I have to write other to handle second scenario.
By the way query will be dealing with million of records in table so performance must be very good.
Got answer from Tere J Comments. Following query covers above mentioned both criteria.
SELECT
source_id, `group_id`, GROUP_CONCAT(id) AS faultyIDS
FROM
table
GROUP BY
source_id,group_id
HAVING
COUNT(DISTINCT sortsequence) <> COUNT(sortsequence) OR COUNT(sortsequence) <> MAX(sortsequence) OR MIN(sortsequence) <> 1
May be it can help others.
Try this query it will solve both of the cases as you have mentioned in the question.
SELECT
a.*
FROM
tbl a
INNER JOIN
(select
#rn:=IF(#prevG = group_id AND #prevS = source_id, #rn + 1, 1) As rId,
#prevG:=group_id AS group_id,
#prevS:=source_id AS source_id,
id,
sortsequence
FROM
tbl
join
(select #rn:=0, #prevS:=0, #prevG:=0)b
order by group_id, source_id, id) b
ON a.id = b.id AND a.SORTSEQUENCE <> b.RID;
FIDDLE

Update with a Min in the table

I want to update a Column in a Table, based on the minimum of another column of the same table.
eg.
JobPositonId | JobPositonName | JobDescriptionId | ContactId
1 | 1 | 1 | 1
2 | 1 | 1 | 0
3 | 1 | 1 | 0
I want to update ContactId to be 1, if it is 0 and where JobPositionId is the lowest.
I think this should work:
update jobTable
set contactid = 1
where jobPostitionId in (select pos from (select min(jobPositionId) as pos from jobTable where contactId = 0) as subtable);
It's kind of a hack similar to what's described here (http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/).