How can I consolidate a SQL query as an integer? - mysql

The following SQL (PHP, MySQL) gives me rows with one id per row and the number of matches for each id, as the COUNT() for each.
SELECT ot.id, COUNT(ot.id)
FROM ot
JOIN tm on tm.mediaid = ot.id
WHERE tm.uploadedToS3 = 1
AND (
ot.something IN (1)
OR ot.somethingelse IN (1)
OR ot.anotherthing IN (1)
OR ot.morestuff IN (1)
OR ot.evenmorestuff IN (1)
)
GROUP BY ot.id
The result is something like...
ot.id COUNT(ot.id)
40153 4
40305 3
40309 35
40314 29
40315 12
40317 10
40318 16
40319 14
40324 154
40331 113
I would just like to know how many rows this query returns. I don't need any other information, just one integer. For the above, I am looking for the number of rows, i.e. I'd expect to just get the number 10.
How would I get this?
Thanks.

Use count(distinct) with no group by:
SELECT COUNT(DISTINCT ot.id)
FROM ot JOIN
tm
ON tm.mediaid = ot.id
WHERE tm.uploadedToS3 = 1 AND
(ot.something IN (1)
OR ot.somethingelseIN (1)
OR ot.anotherthing IN (1)
OR ot.morestuff IN (1)
OR ot.evenmorestuff IN (1)
)

Related

How to add subquery to get last record in group by

I would like assistance with adding a subquery into the below query as I understand this is the method I need to use to get the result from the last record for scan_type column, not the first record in the group by due to mysql server running 5.7.
I have tried doing this but I am not understanding how I can put the subquery into the current query. I have tried unsuccessfully which causes the query to error.
Currently I am able to get the date/time stamp by using MAX which gives me the last record for the person's attendance, but I am having trouble getting the related "scan_type". Apart from this, the remainder of the query returns all of the expected results.
Below is the current query:
SELECT A.attendance_sessions_id, A.person_id, A.scan_type, A.absence_type, MAX(A.date_time), B.name, B.student_level
FROM `attendance_record` A
LEFT JOIN `person` B ON A.person_id = B.student_no
WHERE A.scan_type IS NULL
OR A.scan_type <> 'evac_scan'
OR A.scan_type NOT LIKE 'evac_%'
GROUP BY A.attendance_sessions_id, A.person_id
Below is the current output of the above query:
attendance_sessions_id
person_id
scan_type
absence_type
MAX(A.date_time)
name
student_level
1
65
scan_in
NULL
2022-02-06 12:59:48
Chris
Year 1
Expecting scan_type = "scan_out"
attendance_record table:
attendance_record_id
attendance_sessions_id
person_id
scan_type
absence_type
date_time
4
1
65
scan_in
NULL
2022-02-05 20:13:17
5
1
65
scan_out
NULL
2022-02-05 20:14:39
6
1
65
scan_in
NULL
2022-02-06 12:06:45
7
1
65
evac_scan
NULL
2022-02-06 12:53:01
8
1
65
scan_out
NULL
2022-02-06 12:59:48
person table:
person_id
student_no
name
student_level
9
65
Chris
Year 1
attendance_sessions table:
attenance_sessions_id
session_name
session_date_time
1
February Weekend 1
2022-02-05 00:01:00
Since some time only_full_group_by is the default, (at least for MySQL 8+ ). It would be great to change this query in such a way that it's handled correctly, als in the furture.
SELECT
x.attendance_sessions_id,
x.person_id,
A.scan_type,
A.absence_type,
x.max_date_time,
B.name,
B.student_level
FROM (
SELECT
A.attendance_sessions_id,
A.person_id,
-- A.scan_type,
-- A.absence_type,
MAX(A.date_time) as max_date_time,
-- B.name,
-- B.student_level
FROM `attendance_record` A
-- LEFT JOIN `person` B ON A.person_id = B.student_no
WHERE A.scan_type IS NULL
OR A.scan_type <> 'evac_scan'
OR A.scan_type NOT LIKE 'evac_%'
GROUP BY
A.attendance_sessions_id,
A.person_id
) x
INNER JOIN `attendance_record` A ON A.attendance_sessions_id = x.attendance_sessions_id
AND A.person_id = x.person_id
AND A.date_time = x.max_date_time
LEFT JOIN `person` B ON B.student_no = A.person_id
Removed some columns (--) because of the only_full_group_by setting, and removed the LEFT JOIN because in the current sub-query the table person is no longer used.
Changed query to sub-query, and added all (remove)fields to the outer query which also includes a JOIN to get the MAX record from attendance_record
NOTE: When there are multiple records with the same date_time for one attendance_sessions_id,person_id, this query will not produce correct results.

How to do counts across 2 tables

I have searched for hours for a solution to this mysql user case. I have found many examples but none of them had composite primary keys. I want to do a count across 2 tables and also calculate a difference. Here are the two separate queries
primary key testId, tpId
SELECT Count(*) AS count,
testid,
tpid
FROM cicdexpecteddocument e
WHERE e.testid = 8
GROUP BY e.tpid;
3 8 756abdaa-31c0-11ea-9c52-0245f4ff0412
3 8 7ea2b31b-31c0-11ea-9c52-0245f4ff0412
1 8 c25780cb-31c0-11ea-9c52-0245f4ff0412
2 8 c9f70ed9-31c0-11ea-9c52-0245f4ff0412
primary key testId, tpId, executionId
SELECT Count(*) AS count,
testid,
tpid
FROM cicdactualdocument a
WHERE a.testid = 8
AND a.executionid =
'execution-d0c5e270-50f2-472e-a609-ac2c381e0a5f-2020.01.09'
GROUP BY tpid;
2 8 7ea2b31b-31c0-11ea-9c52-0245f4ff0412
2 8 c25780cb-31c0-11ea-9c52-0245f4ff0412
2 8 c9f70ed9-31c0-11ea-9c52-0245f4ff0412
I would like to end up with something like
3 3 8 756abdaa-31c0-11ea-9c52-0245f4ff0412
3 2 1 8 87ea2b31b-31c0-11ea-9c52-0245f4ff0412
1 2 -1 8 8c25780cb-31c0-11ea-9c52-0245f4ff0412
2 2 0 8 8c9f70ed9-31c0-11ea-9c52-0245f4ff0412
Any guidance is appreciated. Thank you in advance
Here's the code. See below for an explanation.
SELECT count_t1, count_t2,
IFNULL(count_t1, 0) - IFNULL(count_t2, 0) AS diff,
t1.testid, t1.tpid
FROM (
SELECT COUNT(*) AS count_t1,
testid,
tpid
FROM cicdexpecteddocument e
WHERE e.testid = 8
GROUP BY e.tpid
) AS t1
LEFT OUTER JOIN
(
SELECT COUNT(*) AS count_t2,
testid,
tpid
FROM cicdactualdocument a
WHERE a.testid = 8 AND a.executionid =
'execution-d0c5e270-50f2-472e-a609-ac2c381e0a5f-2020.01.09'
GROUP BY tpid
) AS t2 ON t1.testid = t2.testid AND t1.tpid = t2.tpid
ORDER BY tpid
Dissecting this:
Skip past the SELECT columns and notice how the two queries that you specified for each table are contained in parenthesis followed by "AS t1" (or t2) -- those are subqueries. After the 2nd subquery (2nd to last line) is where I specified the join condition.
Next is how the "diff" column is calculated. It uses the IFNULL() function which returns the value specified in the 2nd parameter if the primary value is NULL. That allows the database to do the calculation even on NULL values.
Note: I just put this together quick and dirty, but I'm not making any assumptions about speed here. If you have a couple hundred rows, no big deal. But if you're dealing with thousands of rows in each table, you may need to work on optimizing this query.
Hope that helps!

Find contiguous numbers ranges with mysql (25.000+ table rows)

I need to find contiguous numbers ranges (min, max) from a set of "series" (only numbers).
I have written a SQL using #row_number but it works partially. If the row ID (int, primary, auto_increment) is not consecutive, it returns 2 result sets instead of just one.
Check this sqlfiddle to see how the query works.
So I need to find a way to do this not using #row_number or using it but with a condition to "bind" the 2 results into single one is the series are consecutive (even if the ID is not consecutive).
The correct result should be: (see this sqlfiddle)
MIN MAX PRODUCT_ID
220 230 20
1106 1108 18
1110 1110 18
1112 1120 18
Response time is also important.
Thanks
I assume that you're after something like this...
SELECT a.product_id
, a.series start
, MIN(c.series) end
FROM card a
LEFT
JOIN card b
ON b.product_id = a.product_id
AND b.series = a.series - 1
LEFT
JOIN card c
ON c.product_id = a.product_id
AND c.series >= a.series
LEFT
JOIN card d
ON d.product_id = a.product_id
AND d.series = c.series + 1
WHERE b.series IS NULL
AND c.series IS NOT NULL
AND d.series IS NULL
GROUP
BY a.product_id
, a.series;
http://sqlfiddle.com/#!2/32dc8/4
If performance remains an issue, then we can take another look at a solution with #variables

Get sum of value with inner join mysql

I have a table for terminal
Id status
1 Online
2 Offline
3 Offline
and I have a separate table where I can find the total hours/date of the up and downtime.
total_time
Id up down
1 10 14
2 20 4
3 15 9
1 5 19
2 4 20
3 10 14
I want to display the terminal id, status and the TOTAL up and downtime(1 = 15(up), 2 = 24(up), 3 = 25(up). I'm using inner join and I have no idea how i will be able to get the sum of the up and downtime..
SELECT terminal.Id, terminal.status, total_time.Id, SUM(total_time.up),SUM(total_time.down)
FROM terminal
INNER JOIN total_time
ON terminal.Id = total_time.Id
WHERE terminal.Id = total_time.Id
Something like this should do the trick. I am interpreting your question as asking for only the sum of the time of the current status. If this is not what you want (and maybe you want the sum of both times), please let me know.
SELECT t.id, t.status, IF(t.status = 'Online', ttlTime.upTime, ttlTime.downTime) as totalTime
FROM terminal t
JOIN
(SELECT tt.id, SUM(tt.up) as upTime, SUM(tt.down) AS downTime
FROM total_time tt
GROUP BY tt.id) ttlTime ON t.id = ttlTime.id
See the SQLFiddle
You get "inner sums" by using the GROUP BY clause.
Try:
SELECT terminal.Id, SUM(total_time.up), SUM(total_time.down)
FROM terminal
INNER JOIN total_time
ON terminal.Id = total_time.Id
GROUP BY terminal.Id
SELECT DISTINCT terminal.Id, terminal.status, total_time.Id, SUM(total_time.up),SUM(total_time.down)
FROM terminal
INNER JOIN total_time
ON terminal.Id = total_time.Id
Should do it. The DISTINCT clause acts as a filter to remove duplicate records from a result set.

Mysql Count per column

I have the following query:
SELECT a.feeder_id, b.feeder_pr
FROM authors_article_feeders a
LEFT JOIN feeders b ON b.id = a.feeder_id
WHERE website_id =1
LIMIT 0 , 30
which results in:
feeder_id feeder_pr
18 2
18 2
18 2
18 2
32 6
What I need is to modify the above query so that it will manipulate this data so that the result would end up with a count of each feeder_pr, so in this case the result would be:
feeder_pr count
2 4
6 1
Any assistance is appreciated. If you have time please describe your solution so that I can learn from it while I'm at it.
Everything I've tried has ended in inaccurate results, usually with just one row instead of the expected 2.
You just need to add a GROUP BY And, you would not even need the joins
SELECT b.feeder_pr, COUNT(b.feeder_pr)
FROM feeders b
GROUP BY b.feeder_pr
SELECT b.feeder_pr, count(a.feeder_id) as count
FROM authors_article_feeders a
LEFT JOIN feeders b ON b.id = a.feeder_id
WHERE website_id =1
GROUP BY 1