Mysql Update + SELECT query - mysql

I want to update data table for those who score exam id 1,2 more than 80. I try this
UPDATE data
SET column = 'value'
WHERE
(SELECT * FROM exams
WHERE (id = '1' AND score >= 80) AND (id = '2' AND score >= 80));
It gives me 0 result. But it should have few hundreds results ANy help??
I think the problem is this:
SELECT * FROM exams
WHERE (id = '1' AND score >= 80) AND (id = '2' AND score >= 80)
It gives 0 result. How to select those who score more than 80 points for both exam 1 and 2??

You query won't work because you're asking for exams that have id = 1 AND id = 2.
Assuming that id cannot hold two values at the same time, you'll never return any results.
Try this as the basis of your update instead :-
SELECT * FROM exams
WHERE score >= 80 AND id IN ( '1','2' )
Edited based on comment :-
User wants only people who scored more than 80 for both exams. Assuming personid is a key to the person who took the exam.
SELECT e1.personid FROM
(
SELECT personid FROM exams WHERE score >= 80 AND id = '1'
) e1
INNER JOIN
(
SELECT personid FROM exams WHERE score >= 80 AND id = '2'
) e2
ON
e1.personid = e2.personid

I believe your select statement should use an OR:
SELECT * FROM exams
WHERE (id = '1' AND score >= 80) OR (id = '2' AND score >= 80)

Try this:
SELECT * FROM exams
WHERE (id = '1' OR id = '2') AND score >=80
Because you cannot have id ='1' and id = '2' simultaneously the number of values returned in your case is 0.

Related

mysql GROUP CONCAT not returning values

Here is my query
SELECT
SUM(o.order_disc + o.order_disc_vat) AS manualsale
FROM
orders o
WHERE
o.order_flag IN (0 , 2, 3)
AND o.order_status = '1'
AND (o.assign_sale_id IN (SELECT GROUP_CONCAT(CAST(id AS SIGNED)) AS ids FROM users WHERE team_id = 92))
AND DATE(o.payment_on) = DATE(NOW())
above query return null when i run this query in terminal
When i use subquery below it returns data
SELECT GROUP_CONCAT(CAST(id AS SIGNED)) AS ids FROM users WHERE team_id = 92)
above query returns
'106,124,142,179'
and when i run my first query like below
SELECT
SUM(o.order_disc + o.order_disc_vat) AS manualsale
FROM
orders o
WHERE
o.order_flag IN (0 , 2, 3)
AND o.order_status = '1'
AND (o.assign_sale_id IN (106,124,142,179))
AND DATE(o.payment_on) = DATE(NOW())
it return me value.
Why it is not working with subquery please help
This does not do what you want:
AND (o.assign_sale_id IN (SELECT GROUP_CONCAT(CAST(id AS SIGNED)) AS ids FROM users WHERE team_id = 92))
This compares a single value against a comma-separated list of values, so it never matches (unless there is just one row in users for the given team).
You could phrase this as:
AND assign_sale_id IN (SELECT id FROM users WHERE team_id = 92)
But this would probably be more efficently expressed with exists:
AND EXISTS(SELECT 1 FROM users u WHERE u.team_id = 92 AND u.id = o.assign_sale_id)
Side note: I would also recommend rewriting this condition:
AND DATE(o.payment_on) = DATE(NOW())
To the following, which can take advantage of an index:
AND o.payment_on >= current_date AND o.payment_on < current_date + interval 1 day

MS SQL query with multiple search criteria across rows

I have below table and SQL query written, this query should not return any result but its returning ID = 1 , what is wrong with the SQL query? Can anyone please help?
** Note balance data type is decimal rest are varchar
ID code balance level
1 C 150.00
1 P 40027.42 F
1 P 40027.42 F
select distinct ID from table
(
(code = 'P' and balance = 40027.42 and level = 'F') or
(code = 'C' and balance = 151.00 )
)
group by ID
having count(ID) >=2
If you do not want to count the same code twice, you can use count(distinct code):
select ID
from t
where (code = 'P' and balance = 40027.42 and level = 'F')
or (code = 'C' and balance = 151.00 )
group by ID
having count(distinct code) >=2
If you want to only count a distinct set of values once, you can use a derived table/subquery to select distinct rows:
select ID
from (
select distinct id, code, balance, level
from t
) as s
where (code = 'P' and balance = 40027.42 and level = 'F')
or (code = 'C' and balance = 151.00 )
group by ID
having count(ID) >=2
rextester demo for both: http://rextester.com/LBKO57534

SQL code: adding value to one code but shown in other code as well

could somebody help me with this, please? I was checking answers around the net but still not successful.
I have two codes, code #1:
SELECT subject_note,ticket_id,created_time,status,
UPPER(SUBSTRING(datacenter,1,3)) region
FROM sort_ticket WHERE ticket_type = 1 AND status =0 AND team_type = 1 AND MONTH(FROM_UNIXTIME(closed_date)) = MONTH(NOW())
and YEAR(FROM_UNIXTIME(closed_date)) = YEAR(NOW())
AND
(
-- ASH
owner_id = 812400897
or owner_id = 1392249056
or owner_id = 739243661
or owner_id = 100002941128738
or owner_id = 619251675
or owner_id = 502392893
)
and code #2:
SELECT
subject_note,
cyborg_verify_tries,
ticket_id,
closed_date,
created_time,
status,
UPPER(SUBSTRING(datacenter,1,3)) region
FROM sort_ticket
WHERE ticket_type = 1
AND status =0
AND team_type = 1
and (FROM_UNIXTIME(closed_date)) >= DATE_SUB(now(), INTERVAL 6 MONTH)
AND
(
-- ASH
owner_id = 812400897
or owner_id = 1392249056
or owner_id = 739243661
or owner_id = 100002941128738
or owner_id = 619251675
or owner_id = 502392893
)
Both of these codes creating table and giving me the results what is good.
Problem what I have in here is I have to add manually every NEW "owner_id" into each code.
Is there any way how I could add NEW "owner_id" only into any code and second would be updated automatically? Both info are taken from the same table "sort_ticket".
Thank you for all the help.
You can use an extra table, where you put in the user id's and replace the fixed values with a select on this data:
SELECT
subject_note,
cyborg_verify_tries,
ticket_id,
closed_date,
created_time,
status,
UPPER(SUBSTRING(datacenter,1,3)) region
FROM sort_ticket
WHERE ticket_type = 1
AND status =0
AND team_type = 1
and (FROM_UNIXTIME(closed_date)) >= DATE_SUB(now(), INTERVAL 6 MONTH)
AND
(
-- ASH
select owner_id from newtable
)
same in the other select
You can use an additional table or an additonal view. Use a join to the new table/view in your queries and add new owner_id with an insert in the table or an UNION in the view.
To solve your proble with a view you can do this:
CREATE VIEW v_sort_ticket_owner AS
SELECT 812400897 as owner_id
UNION
SELECT 1392249056 as owner_id
UNION
SELECT 739243661 as owner_id
UNION
SELECT 100002941128738 as owner_id
UNION
SELECT 619251675 as owner_id
UNION
SELECT 502392893 as owner_id
--UNION
--SELECT newnumber as ownder_id
SELECT subject_note,ticket_id,created_time,status,
UPPER(SUBSTRING(datacenter,1,3)) region
FROM sort_ticket st
JOIN v_sort_ticket_owner sto
ON st.owner_id = sto.owner_id
WHERE st.ticket_type = 1 AND st.status =0 AND st.team_type = 1 AND
MONTH(FROM_UNIXTIME(st.closed_date)) = MONTH(NOW())
and YEAR(FROM_UNIXTIME(st.closed_date)) = YEAR(NOW())

fetch no of rows from table 2 with id of table 1

I have some thing to do here with subquery but I am not able to do.
I want the result from a table with a extra field to show to no of results from other table with a column value from table 1.
table1:
CountryId Country ISO2 ISO3
table2:
id noof_country state
I have to retrive noof_country count in table 1 as count field
EDIT
my actual tables are
table 1:
ad_id job_country status delete days_left
table 2:
CountryId Country ISO2 status
I have done query in two phase:
$sql_map = "select distinct c.ISO2, c.Country, a.job_country
from rec_countries c, rec_advert a
where c.status = 1
and DATE(a.modified_date) >= CURDATE() - INTERVAL 30 DAY
and c.ISO2 <> '--'
and c.ISO2 <> ''
and c.CountryId = a.job_country
and a.status = 1
and a.`delete` = 0
and a.days_left >0
";
$res = mysql_query($sql_map);
while($row = mysql_fetch_array($res)){
$jobs_no = count($row['job_country']);
$sql_job = "SELECT COUNT( job_country ) AS jobs_no
FROM rec_advert
WHERE job_country = ".$row['job_country']."
and status = 1
and `delete` = 0
and days_left >0";
$resjob=mysql_query($sql_job);
$rowjob = mysql_fetch_array($resjob);
//here jobs_no is the count of total rows
}
Here I want to do with subquery.
If I read the question right, this should work:
SELECT
CountryId,
Country,
ISO2,
ISO3,
(
SELECT COUNT(DISTINCT noof_country)
FROM table2
WHERE table2.id = table1.CountryId
) AS noof_country_count
FROM table1
It's not immediately clear in your question which column in table1 is a foreign key to which column in table2... or if they are even related that way. If this query doesn't work for you, please clarify your schema.
Based on your updated information, try this:
select distinct c.ISO2, c.Country, a.job_country,
(
select COUNT(a2.job_country)
from rec_advert a2
where a2.job_country = a.job_country
and a2.status = 1
and a2.`delete` = 0
and a2.days_left >0
) as jobs_no
from rec_countries c, rec_advert a
where c.status = 1
and DATE(a.modified_date) >= CURDATE() - INTERVAL 30 DAY
and c.ISO2 <> '--'
and c.ISO2 <> ''
and c.CountryId = a.job_country
and a.status = 1
and a.`delete` = 0
and a.days_left >0

SQL: query with complex subqueries

I have the following tables in my game's database:
rankedUp (image_id, user_id, created_at)
globalRank (image_id, rank )
matchups (user_id, image_id1, image_id2)
All image_ids in globalRank table are assigned a rank which is a float from 0 to 1
Assuming I have the current logged in user's "user_id" value, I'm looking for a query that will return a pair of image ids (imageid1, imageid2) such that:
imageid1 has lower rank than imageid2 but is also the next highest rank less than imageid2
matchups table doesn't have (userid,imageid1,imageid2) or (userid,imageid2,imageid1)
rankedup table doesn't have (userid,imageid1) or if it does, the createdat column is older than X hours
What I have so far for requirement 1 is this:
SELECT lowerImages.image_id AS lower_image, higherImages.image_id AS higher_image
FROM global_rank AS lowerImages, global_rank AS higherImages
WHERE lowerImages.rank < higherImages.rank
AND lowerImages.image_id = (
SELECT image_id
FROM (
SELECT image_id
FROM global_rank
WHERE rank < higherImages.rank
ORDER BY rank DESC
LIMIT 1 , 1
) AS tmp
)
but it doesnt work because I can't reference higherImages.rank in the subquery.
Does anyone know how I could satisfy all of those requirements in one query?
Thanks for your help
EDIT:
I now have this query but I don't know about the efficiency and I need to test it for correctness:
SELECT lowerImages.image_id AS lower_image,
max(higherImages.image_id) AS higher_image
FROM global_rank AS lowerImages, global_rank AS higherImages
WHERE lowerImages.rank < higherImages.rank
AND 1 NOT IN (select 1 from ranked_up where
lowerImages.image_id = ranked_up.image_id
AND ranked_up.user_id = $user_id
AND ranked_up.created_at > DATE_SUB(NOW(), INTERVAL 1 DAY))
AND 1 NOT IN (
SELECT 1 from matchups where user_id = $userId
AND lower_image_id = lowerImages.image_id
AND higher_image_id = higherImages.image_id
UNION
SELECT 1 from matchups where user_id = $user_id
AND lower_image_id = higherImages.image_id
AND higher_image_id = lowerImages.image_id
)
GROUP BY 1
the "not in" statements I'm using are all indexed so they should run fast. The efficiency problem I have is the group by and selection of the global_rank tables
This question is a revision of Pretty Complex SQL Query, which should no longer be answered.
select
(
select image_id, rank from
rankedup inner join globalRank
on rankedup.image_id = globalRank .image_id
where user_id = XXX
limit 1, 1
) as highest,
(
select image_id, rank from
rankedup inner join globalRank
on rankedup.image_id = globalRank .image_id
where user_id = XXX
limit 2, 1
) as secondhighest
I normally use SQL Server, but this i think is the translation for mysql :)
This should do the trick:
SELECT lowerImages.*, higherImages.*
FROM globalrank AS lowerImages, globalrank AS higherImages
WHERE lowerImages.rank < higherImages.rank
AND lowerImages.image_id = (
SELECT image_id
FROM (
SELECT image_id
FROM globalrank
WHERE rank < higherImages.rank
ORDER BY rank DESC
LIMIT 1,1
) AS tmp
)
AND NOT EXISTS (
SELECT * FROM matchups
WHERE user_id = $user_id
AND ((image_id1 = lowerImages.image_id AND image_id2 = higherImages.image_id)
OR (image_id2 = lowerImages.image_id AND image_id1 = higherImages.image_id))
)
AND higherImages.image_id NOT IN (
SELECT image_id FROM rankedup
WHERE created_at < DATE_ADD(NOW(), INTERVAL 1 DAY)
AND USER_ID <> $user_id
)
ORDER BY higherImages.rank
I'm assuming the PKs of matchups and rankedup include all columns in those tables. This would allow the second 2 sub-queries to utilize the PK indexes. You would probably want an ordered index on globalrank.rank to speed up the first sub-query.