How can count my result on my table in MySQL - php

I have a table for exam result, how can I filter and count my "correct" values on my table and somehow group them by User Number and Module? for example, i only want to count my "correct" values:

SELECT
UserNo, ModuleNo, COUNT(QuestionResult) as correctanswers
FROM yourtablename
WHERE
QuestionResult='Correct'
GROUP BY
UserNo, ModuleNo
You have to group twice if you want it grouped by the user and the module.

First solution using SUM and CASE
SELECT `UserNo` ,
SUM(CASE WHEN `QuestionResult` = 'Correct' THEN 1 ELSE 0 END) AS QuestionResultCount ,
`Module`
FROM `TableName`
GROUP BY `UserNo` ,
`Module`
Second solution using COUNT and WHERE clause :
(Note: This could be better for large tables with proper indexes, since the DBE can use that index to filter the table while it can not be done with any CASE..WHEN based solutions.)
SELECT `UserNo` ,
COUNT(`QuestionResult`) AS QuestionResultCount ,
`Module`
FROM `TableName`
WHERE `QuestionResult` = 'Correct'
GROUP BY `UserNo` ,
`Module`
Third solution using COUNT and CASE :
SELECT `UserNo` ,
COUNT(CASE WHEN `QuestionResult` = 'Correct' THEN `QuestionResult` END) AS QuestionResultCount ,
`Module`
FROM `TableName`
GROUP BY `UserNo` ,
`Module`
SQLFiddle

Two alternatives:
Using CASE:
SELECT UserNo,
SUM(CASE WHEN QuestionResult = 'Correct' THEN 1 ELSE 0 END) as QuestionResult,
ModuleNo as Module
FROM TableName
GROUP BY `UserNo`,ModuleNo
ORDER BY ModuleNo,UserNo
Result:
USERNO QUESTIONRESULT MODULE
123456 3 1
987456 2 1
123456 4 2
987456 1 2
See result in SQL Fiddle.
Using WHERE caluse:
SELECT UserNo,
COUNT(QuestionResult) as QuestionResult,
ModuleNo as Module
FROM TableName
WHERE QuestionResult = 'Correct'
GROUP BY `UserNo`,ModuleNo
ORDER BY ModuleNo,UserNo
See result in SQL Fiddle.

Use COUNT
SELECT UserNo,
COUNT(QuestionResult)
FROM TABLE
WHERE QuestionResult = 'Correct'
GROUP BY ModuleNo, ModuleNo

Related

How to find first and last values within query sorted by another column

I am new to coding and this is the most complex query I have tried writing.
I am trying to create a query that will find the first and last entry for meters sorted by bunker_id within a date range. There are 12 different systems that have their meters captured when they are used.
I have several MySQL tables to track usage of systems and component configurations.
One table has a log of meters for all the systems. What I am trying to do is query this table between Date A and Date B, and receive the first and last meter values within the date range for each system. They systems may not be used everyday, but on occasion will have multiple entries in a day.
I am looking to have a query run through POST on a web page with selectors for the days and the system id's. The data will be output into an HTML table.
date
bunker_id
power_on_hours
01-01-2022
A
26115.50
01-02-2022
B
28535.13
01-02-2022
A
26257.38
01-03-2022
B
28682.73
What I am trying to return
bunker_id
starting_meters
ending_meters
A
26115.50
26257.38
B
28535.13
28682.73
The query that I have sets the starting and ending hours as the same value. I tried using MAX and MIN, but everything breaks if someone were to enter 0 for the meter.
SELECT
lu_bunkers.bunker_name as 'bunker_name',
lu_bunkers.bunker_sn,
SUM(system_utilization.hours_used) as 'total_hours',
SUM(CASE WHEN system_utilization.use_id = '1' THEN system_utilization.hours_used ELSE 0 END) as 'maintenance_hours',
SUM(CASE WHEN system_utilization.use_id = '2' THEN system_utilization.hours_used ELSE 0 END) as 'working_rf_hours',
SUM(CASE WHEN system_utilization.use_id = '3' THEN system_utilization.hours_used ELSE 0 END) as 'working_no_rf_hours',
SUM(CASE WHEN system_utilization.use_id = '4' THEN system_utilization.hours_used ELSE 0 END) as 'acd_hours',
((SUM(system_utilization.hours_used))/ ((DATEDIFF('2022-02-24', '2021-01-01')+1)*5/7*12))*100 as net_utilization,
((DATEDIFF('2022-02-24', '2021-01-01')+1)*(5/7)*12) as num_hours,
(SELECT system_meters.power_on_hours WHERE system_utilization.date_used BETWEEN '2021-01-01' AND '2022-02-24' ORDER BY system_utilization.date_used DESC LIMIT 1) as 'ending_hours',
(SELECT system_meters.power_on_hours WHERE system_utilization.date_used BETWEEN '2021-01-01' AND '2022-02-24' ORDER BY system_utilization.date_used ASC LIMIT 1) as 'starting_hours'
FROM system_utilization
LEFT JOIN lu_bunkers ON system_utilization.bunker_id = lu_bunkers.bunker_id
LEFT JOIN lu_use ON system_utilization.use_id = lu_use.use_id
LEFT JOIN system_meters ON system_utilization.id = system_meters.utilization_id
WHERE system_utilization.date_used BETWEEN '2021-01-01' AND '2022-02-24' AND system_utilization.bunker_id LIKE '%'
GROUP BY system_utilization.bunker_id
ORDER BY lu_bunkers.bunker_name
2 possible solutions
Using Joins
SELECT
a.`bunker_id`,
b.`power_on_hours` as `starting_meters`,
c.`power_on_hours` as `ending_meters`
FROM `yourtable` a
LEFT JOIN `yourtable` b
ON (
SELECT `date`
FROM `yourtable`
WHERE `bunker_id` = a.`bunker_id`
ORDER BY `date`
LIMIT 1
) = b.`date`
AND a.`bunker_id` = b.`bunker_id`
LEFT JOIN `yourtable` c
ON (
SELECT `date`
FROM `yourtable`
WHERE `bunker_id` = a.`bunker_id`
ORDER BY `date` DESC
LIMIT 1
) = c.`date`
AND a.`bunker_id` = c.`bunker_id`
GROUP BY a.`bunker_id`
Using subqueries on columns
SELECT
a.`bunker_id`,
(
SELECT `power_on_hours`
FROM `yourtable`
WHERE `bunker_id` = a.`bunker_id`
ORDER BY `date` LIMIT 1
) as `starting_meters`,
(
SELECT `power_on_hours`
FROM `yourtable`
WHERE `bunker_id` = a.`bunker_id`
ORDER BY `date` DESC LIMIT 1
) as `ending_meters`
FROM `yourtable` a
GROUP BY a.`bunker_id`

Getting Count with different conditions in Select Query

The scenario is I have a column named "States" in a table, States can be 0,1,2,3 or 4. What I want to do is get a count of each state using WHERE State = in a single query.
The main purpose is I want to show the count of records (identified by their state). Like this, 20 records have State 0 etc.
Is this possible? If yes, then how can I achieve this?
Edit: I know about Count. Here's what I have tried:
SELECT State, Date_Created, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=1) as State_One, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=2) as State_Two, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=0) as State_Zero, (SELECT COUNT(Id) FROM [ECOS].[eco].[tb_projects_details] WHERE State=4) as State_Four FROM [ECOS].[eco].[tb_projects_details] WHERE Date_Created < dateadd(week,-3,getdate());
If I understand it correctly, you want to group and count:
SELECT mt.States, COUNT(*) total
FROM my_table mt
GROUP BY mt.States
To generate a list of values and their counts you can do this:
SELECT State, COUNT(*) AS C
FROM mytable
GROUP BY State
To generate one row that contains value counts as columns you can do this:
SELECT
COUNT(CASE State WHEN 0 THEN 1 ELSE NULL END) AS State_0_Count,
COUNT(CASE State WHEN 1 THEN 1 ELSE NULL END) AS State_1_Count,
COUNT(CASE State WHEN 2 THEN 1 ELSE NULL END) AS State_2_Count,
COUNT(CASE State WHEN 3 THEN 1 ELSE NULL END) AS State_3_Count,
COUNT(CASE State WHEN 4 THEN 1 ELSE NULL END) AS State_4_Count
FROM [...]
WHERE [...]
It will be very easy if you use group by clause after where condition. Then you will get the number of each state very easily.
SELECT state, count(*)
FROM table_name
GROUP BY state
Next time read a sql for beginers book first.
Select state, count(*)
from table
group by state

Can I select more counts in one query?

I have a table with a field called type, where 3 various rows are possible: 1, 2 and 3.
Now, I don't care about 3 at all. I need to count how many rows there are with type = 1 and with type = 2. I am doing this with 2 queries, like this:
Query1: SELECT COUNT(id) as count FROM users WHERE type='1'
Query2: SELECT COUNT(id) as count FROM users WHERE type='2'
Can I do this with only 1 single query? If so, should I, or not? How would the query look?
SELECT type,
COUNT(id) AS count
FROM users
WHERE type IN ('1','2')
GROUP BY type
SELECT type, COUNT(id) AS count
FROM users
GROUP BY type
HAVING type < 3
SELECT sum(case when type = '1' then 1 else 0 end) as count_for_one,
sum(case when type = '2' then 1 else 0 end) as count_for_tow
FROM users
WHERE type IN ('1','2')
If you want separate numbers,
SELECT SUM(IF(type='1', 1, 0)), SUM(IF(type='2', 1, 0))
FROM users WHERE type IN ('1', '2')

Can I do this in one Mysql query?

I have a table with two columns:
column A column B
1 2
1 2
2 1
I want to return total of ones = 3 total of twos = 3
The best I can come up with is two queries like so:
SELECT sum(CASE WHEN columnA =1 THEN 1 ELSE 0 END )
+ sum(CASE WHEN columnB =1 THEN 1 ELSE 0 END )
SELECT sum(CASE WHEN columnA =2 THEN 1 ELSE 0 END )
+ sum(CASE WHEN columnB =2 THEN 1 ELSE 0 END )
Can this be done in one query?
Thanks
You didn't specify if you want to do this as 2 rows or as 2 values in a row.
Two rows are somewhat obvious (just union together all the values from each columns, and count(1) group by value against the result of the union; so I'll assume you want to do one row.
If you only have 1s or 2s, it's simple:
SELECT SUM(A+B-2) 'twos', SUM(4-A-B) 'ones' FROM myTable
SELECT SUM(IF(columnA=1, 1, 0) + IF(columnB=1, 1, 0)) as ones,
SUM(IF(columnA=2, 1, 0) + IF(columnB=2, 1, 0)) as twos
FROM myTable;
C.
To get everything in one query, I would try something like this.
SELECT Result.Val, COUNT(Result.Val) AS Count
FROM (
SELECT ColumnA AS Val
FROM TableName
UNION
SELECT ColumnB AS Val
FROM TableName
) AS Result
GROUP BY Result.Val
In general, you would count things like so:
SELECT columnA, COUNT(*) FROM myTable
GROUP BY columnA
to get the count of all different values in columnA.
SELECT COUNT(*) FROM table WHERE columnA=1 or columnB=1

getting non-distinct results from a distinct mysql query

Right, another question on queries (there must be a syntax guide more helpful than mySQL's manual, surely?)
I have this query (from another helpful answer on SO)...
SELECT DATE_FORMAT(`when`, '%e_%c_%Y')date, COUNT(`ip`) AddressCount FROM `Metrics` WHERE `ID` = '1' GROUP BY DATE(`when`)
I now want to do a similar query to get unique/distinct results for the IPs... i.e. unique visitors per date. My query was this...
SELECT DATE_FORMAT(`when`, '%e_%c_%Y')date, COUNT(distinct `ip`) AddressCount FROM `Metrics` WHERE `ID` = '1' GROUP BY DATE(`when`)
However, that returns a repetition of dates, though different quantities of Addresscount...
date AddressCount
29_6_2009 1
30_6_2009 1
29_6_2009 1
30_6_2009 1
29_6_2009 1
NULL 1
15_5_2009 1
14_5_2009 2
NULL 3
14_5_2009 4
15_5_2009 1
26_6_2009 1
29_6_2009 1
26_6_2009 1
15_5_2009 1
26_6_2009 1
29_6_2009 1
Any ideas on where I'm going wrong?
Your group by will need to match the data you're selecting, so this should work:
SELECT DATE_FORMAT(`when`, '%e_%c_%Y')date, COUNT(distinct `ip`) AddressCount FROM `Metrics` WHERE `ID` = '1' GROUP BY date
Try
SELECT DATE_FORMAT(when, '%e_%c_%Y')date, COUNT(distinct ip) AddressCount FROM Metrics WHERE ID = '1' GROUP BY date(when)
You might have run into some bugs when using reserved words in MySQL

Categories