How to exclude un-wanted records from a query - php

I have a MySQL statement that I need a little bit of help with. I am pulling the data correctly but I just need a some help excluding the records that are not need. If the candidate remaining attempts equal 0 I do not want to pull that record, but as you can see the I am using a subquery to generate the number of remining attempts a candidate may have.
Is there a way to use the remaining_attempts field in the WHERE statement to exclude the un-wanted records?
SELECT (
SELECT count(*) AS Number_Attempts_Used
FROM candidate_exam_record
WHERE candidate_exam_record.idcandidate_eligibilty = candidate_eligibilty.idcandidate_eligibilty
) AS remaining_attempts
, (
SELECT CASE WHEN count(*) > '0' THEN candidate_exam_record.idcandidate_eligibilty END
FROM candidate_exam_record
WHERE candidate_exam_record.idcandidate_eligibilty = candidate_eligibilty.idcandidate_eligibilty) AS EL_ID
FROM candidate_eligibilty
INNER JOIN candidate ON candidate_eligibilty.idcandidate = candidate.idcandidate
INNER JOIN exam ON candidate_eligibilty.exam_id = exam.exam_id
INNER JOIN jurisdiction ON exam.jurisdiction_id = jurisdiction.jurisdiction_id
WHERE jurisdiction.jurisdiction_id = 'xxxx'
AND candidate_eligibilty.eligibility_end_date >= '2013-02-19'
AND remaining_attempts > '0'

It's messy but it looks OK to me. Try changing '0' to just plain old 0. You're storing it as an INT I assume, correct?

Related

SQL Use Subquery results with NOT IN

I can imagine that question exists in some way, but I haven't found what I was looking for.
I need to remove the found values from the result I'm getting in the main query.
Consider the following:
The mainquery:
SELECT idTable
FROM tblTables
WHERE NOT IN idTables = ( **SUBQUERY HERE** )
AND dtSeats >= 4
LIMIT 1;
The subquery:
SELECT idTable
FROM tblTables,tblReservation
WHERE tblTables.idTable = tblReservation.fiTable
AND fiTime = 1
AND dtResDate = "2020-06-16"
In the tblTables there are idTable and dtSeats.
In the tblReservation are fiTime and dtResDate.
The subquery can get up to three rows.
I need to get the first free table with the lowest number of seats possible.
Thanks for helping me out!
Having the DDL and some sample data would be helpful, but I think what you are looking for is a NOT EXISTS clause. It returns everything in the outer query that doesn't match with a record in the inner query.
SELECT idTable
FROM tblTables tt
WHERE NOT EXISTS (
SELECT NULL FROM tblReservation tr WHERE tt.idTable = tr.idTable AND
tr.dtResDate = '2020-06-16'
)
AND dtSeats >= 4
ORDER BY tt.dtSeats
LIMIT 1

Nested count() function with % percentage operation

I’m designing a program for my school to keep student attendance records. So far I have the following query working fine and now I would like to add an IF statement to perform a percentage operation when a certain condition is given. As it is, the query is using INNER JOIN to search for data from two different tables (oxadmain and stuattend) and it’s displaying the results well on a results table:
SELECT o.name
, o.year
, o.photoID
, o.thumbs
, s.ID
, s.studid
, s.date
, s.teacher
, s.subject
, s.attendance
FROM stuattend s
JOIN oxadmain o
ON s.studid = o.stuid
ORDER
BY name ASC
Now I would like to add an “if” statement that
1) finds when stuattend.attendance is = Absent, calculates the percentage of absences the students may have in any given period of time, and then stores that (%) value in “percentage” and
2) ELSE assigns the value of 100% to “Percentage”.
So far I’ve been trying with the following:
<?php $_GET['studentID'] = $_row_RepeatedRS['WADAstuattend']; ?>
SELECT oxadmain.name , oxadmain.year , oxadmain.photoID , oxadmain.thumbs , stuattend.ID , stuattend.studid , stuattend.date , stuattend.teacher, stuattend.subject , stuattend.attendance
CASE
WHEN stuattend.attendance = Absent THEN SELECT Count (studentID) AS ClassDays, (SELECT Count(*) FROM stuattend WHERE studentID = stuattend.studid AND Absent = 1) AS ClassAbsent, ROUND ((ClassAbsent/ClassDays)*100, 2) AS Percentage
ELSE
Percentage = 100
END
FROM stuattend INNER JOIN oxadmain ON stuattend.studid=oxadmain.stuid
ORDER BY name ASC
Any suggestions on how to do this well?
Thank you for your attention
The base idea would be:
select stuattend.studid, sum(stuattend.attendance = `absent`) / count(*)
from stuattend
group by stuaddend.studid;
This very much depends on exactly one entry per student and per day, and of course gets 0 if no absence and 1 if always absent.
To make this a bit more stable I would suggest to write a calendar day table, which simply keeps a list of all days and a column if this is a school day, so workday=1 means they should have been there and workday=0 means sunday or holiday. Then you could left join from this table to the presence and absence days, and even would give good results when presence is not contained in your table.
Just ask if you decide which way to go.

Select child records from tables mysql

I got the bellow piece of select statement that got level 2 child records, having problems to got deeper, can anyone help out?
SELECT
id_mobile AS ID_PROJETO,
UM.qtd_UC,
AM.qtd_AMBIENTE
FROM projetos_mobile AS PM
LEFT JOIN (
SELECT
COUNT(id) AS qtd_UC,
projeto,
data_hora_importacao,
id_uc_mobile
FROM ucs_mobile
WHERE data_hora_importacao = '2015-05-15 17:21:02'
GROUP BY projeto) AS UM
ON PM.id_mobile = UM.projeto
LEFT JOIN (
SELECT
COUNT(id_uc_mobile) AS qtd_AMBIENTE,
id_uc_mobile
FROM ucs_mobile
LEFT JOIN (
SELECT
uc
FROM ambientes_mobile AS s
WHERE data_hora_importacao = '2015-05-15 17:21:02') AS G
ON G.uc = ucs_mobile.id_uc_mobile
WHERE data_hora_importacao = '2015-05-15 17:21:02') AS AM
ON UM.id_uc_mobile = AM.id_uc_mobile
WHERE PM.data_hora_importacao = '2015-05-15 17:21:02'
http://sqlfiddle.com/#!9/2eecf
here is a sqlfiddle if anyone want to try a solution. I have the specific hierarchy: projeto>uc>ambiente>secao>medicoes
ucs_mobile.projeto refers to projetos_mobile.id_mobile
ambientes_mobile.uc refers to ucs_mobile.id_uc_mobile
secoes_iluminacao_mobile.ambiente refers to ambientes_mobile.id_ambiente_mobile
I need a count of each child for the parent I pass, I will have 5 functions that
return the count of each child for a given parent, for example, for a projeto parent I should have count(ucs),count(ambientes),count(secoes),count(medicoes)
So, hope you guys can help me. The database is terrible ugly but that's is what I got. Appreciate any help.
When you have really large queries like this, it can often be helpful to break them down individually, starting from the ground up and patching them together.
I started by just getting the count of each ucs_mobile row for each projetos_mobile value. You can do that by joining the two tables on the related row, and using COUNT(DISTINCT um.id) to get the number of rows. There are other ways to do it, but this particular method will scale better for the rest of your query:
SELECT pm.id, COALESCE(COUNT(DISTINCT um.id), 0) AS qty_uc
FROM projetos_mobile pm
LEFT JOIN ucs_mobile um ON um.data_hora_importacao = '2015-05-15 17:21:02' AND um.projeto = pm.id_mobile
GROUP BY pm.id;
The COALESCE function will be used to fill 0 counts. As long as you remember to use the DISTINCT keyword, and group by the proper id, you can just add in the child rows like so:
SELECT
pm.id,
COALESCE(COUNT(DISTINCT um.id), 0) AS qty_uc,
COALESCE(COUNT(DISTINCT am.id), 0) AS qty_am,
COALESCE(COUNT(DISTINCT sim.id), 0) AS qty_sim
FROM projetos_mobile pm
LEFT JOIN ucs_mobile um ON um.data_hora_importacao = '2015-05-15 17:21:02' AND um.projeto = pm.id_mobile
LEFT JOIN ambientes_mobile am ON am.data_hora_importacao = um.data_hora_importacao AND am.uc = um.id_uc_mobile
LEFT JOIN secoes_iluminacao_mobile sim ON sim.data_hora_importacao = am.data_hora_importacao AND sim.ambiente = am.id_ambiente_mobile
GROUP BY pm.id;
Here is an SQL Fiddle example. NOTE I changed your sample data slightly to ensure my query was working as expected.
Also, a side note. I noticed as you went along that you kept using the same date in your WHERE clauses, so I just joined each table on the date as well, and made sure that in my very first join I looked for the date specified, which in turn will carry its way over to the other tables.

How to optimise this MySQL SQL query?

I'm working with the join plus union plus group by query, and I developed a query something like mentioned below:
SELECT *
FROM (
(SELECT countries_listing.id,
countries_listing.country,
1 AS is_country
FROM countries_listing
LEFT JOIN product_prices ON (product_prices.country_id = countries_listing.id)
WHERE countries_listing.status = 'Yes'
AND product_prices.product_id = '3521')
UNION
(SELECT countries_listing.id,
countries_listing.country,
0 AS is_country
FROM countries_listing
WHERE countries_listing.id NOT IN
(SELECT country_id
FROM product_prices
WHERE product_id='3521')
AND countries_listing.status='Yes')) AS partss
GROUP BY id
ORDER BY country
And I just realised that this query is taking a lot of time to load results, almost 8 seconds.
I was wondering if there is the possibility to optimize this query to the fastest one?
If I understand the logic correctly, you just want to add a flag for the country as to whether or not there is a price for a given product. I think you can use an exists clause to get what you want:
SELECT cl.id, cl.country,
(exists (SELECT 1
FROM product_prices pp
WHERE pp.country_id = cl.id AND
pp.product_id = '3521'
)
) as is_country
FROM countries_listing cl
WHERE cl.status = 'Yes'
ORDER BY country;
For performance, you want two indexes: countries_listing(status, country) and
product_prices(country_id, product_id)`.
Depending on how often it is executed, prepared statements could help. See PDO for more information.

Mysql Join Won't Select

I have been doing a lots of research online and from my understanding i think my query is ok
That is why i need your help to point me out what im doing wrong.
What My Query Should Do
My query should fetch our stock level from both warehouse
Problem Is
if the product is not in both warehouse the query dont give any result.
Ok so first i have two database of warehouse stock level. that look like that.
Databases
-warehouse1
-warehouse2
Table
-product
Columns
-id
-SKU
-qty
So my Query is
SELECT
warehouse1.product.id as 1_id,
warehouse2.product.id as 2_id ,
warehouse1.product.SKU,
warehouse1.product.qty as 1_qty,
warehouse2.product.qty as 2_qty
FROM `warehouse1`.`product`
LEFT JOIN `warehouse2`.`product`
ON
(`warehouse1`.`product`.`SKU` = `warehouse2`.`product`.`SKU`)
WHERE
warehouse1.product.SKU = '$sku'
OR
warehouse2.product.SKU = '$sku'
ORDER BY
(1_qty + 2_qty) DESC
if i make the where clause like this
WHERE warehouse1.product.SKU = '$sku'
it is then working but i can't get stock from both warehouse.
What should i do if i want to receive the stock level from both warehouse even if there is no product that im asking for in this database.
Thanks
Try a FULL OUTER JOIN. You're using a LEFT JOIN. That requires that the DB fetch all records that match your WHERE clause on the LEFT side of the join, which is warehouse1, and any potentially matching records from warehouse2 (the right side of the join). If a SKU exists only in warehouse2, you don't see it.
Switching to a FULL OUTER JOIN forces the DB to fetch all matching records from BOTH sides of the join, regardless of which side(s) the matching records exist on.
you can also do this with a union
(SELECT
warehouse1.product.id as 1_id,
warehouse1.product.SKU,
warehouse1.product.qty as 1_qty
FROM `warehouse1`.`product`
WHERE
warehouse1.product.SKU = '$sku' )
union
(SELECT
warehouse2.product.id as 2_id ,
warehouse2.product.SKU,
warehouse2.product.qty as 2_qty
FROM `warehouse2`.`product`
WHERE warehouse2.product.SKU = '$sku' )
Combine your OR's in () (... OR ...):
SELECT
warehouse1.product.id as 1_id,
warehouse2.product.id as 2_id ,
warehouse1.product.SKU,
warehouse1.product.qty as 1_qty,
warehouse2.product.qty as 2_qty
FROM `warehouse1`.`product`
LEFT JOIN `warehouse2`.`product`
ON
(`warehouse1`.`product`.`SKU` = `warehouse2`.`product`.`SKU`)
WHERE (warehouse1.product.SKU = '$sku'
OR
warehouse2.product.SKU = '$sku')
ORDER BY
(1_qty + 2_qty) DESC

Categories