I need to match the multiple same column value of MySQL table using PHP and MySQL. I am explaining my table below.
db_user:
id status book_id
1 0 22
2 0 22
3 1 22
4 0 23
Here I need the select query and condition is if status=0 for same book_id means if table has lets say book_id=22 and all status=0 then only it will return value true otherwise false. I am writing one example below.
$sql=mysqli_query($connect,"select * from db_user where status=0 and....");
if(mysqli_num_rows($sql) > 0){
$row=mysqli_fetch_array($sql);
$data=$row['book_id'];
}else{
return 0;
}
Here as per the example table only last row will fetch because for book_id=22 there is status=1 present. The data will only fetch when for one book_id all status=0.
One option uses aggregation to check the status values:
SELECT book_id
FROM db_user
GROUP BY book_id
HAVING SUM(CASE WHEN status <> 0 THEN 1 ELSE 0 END) = 0;
We can also use EXISTS:
SELECT DISTINCT t1.book_id
FROM db_user t1
WHERE NOT EXISTS (SELECT 1 FROM db_user t2
WHERE t1.book_id = t2.book_id AND t2.status <> 0);
Back in the day, we would have solved it this way. I say, if it ain't broke, don't fix it...
SELECT DISTINCT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.book_id = x.book_id
AND y.status = 1
WHERE y.id IS NULL;
You could use a not in for the id with status 1
select *
from my_table
where book_id not in (
select book_id
from my_table
where status = 1 )
You can use below query.
select * from db_user where status=0 and book_id not in (select book_id from db_user where status = 1 );
I have tested it and it works.
its very simple:
SELECT book_id,MAX(status) max_status FROM db_user GROUP BY book_id
is max_status is 0 then all is 0 no larger than that.
Related
Hello I have two MySQL Querys where I am trying to use count and results from first select in condition for the second select.
Here is my code:
$sql = "SELECT m.name, m.id
FROM members m
WHERE m.online_status = 1 {$dep} ORDER BY m.name ASC";
$sql_second = "SELECT time_management.clientid, clients.client,
SUM( CASE WHEN MONTH(`date`) = 1 AND taskid <> 1 AND YEAR(date)='$year' THEN TIME_TO_SEC( `time` ) AND user = (result from previouse slect) ELSE 0 END) AS (user_1)
FROM time_management
LEFT JOIN clients ON time_management.clientid = clients.id
WHERE {$dep_where} = {$department_var}
GROUP BY clientid";
So first select is selecting all users which are unknown value. Name and ID
In the second query what I need is to Select for example:
let's say the first query returns
id:1 name: Jon
id:2 name: Mike
id:3 name: Dave
Total results: 3
so in this case in the second query the following line have to be repeaded 3 times for each user:
SUM( CASE WHEN MONTH(`date`) = 1 AND taskid <> 1 AND YEAR(date)='$year' THEN TIME_TO_SEC( `time` ) AND user = (result from previouse slect) ELSE 0 END) AS (user_1)
where user will be = to 1,2,3 for each line and (user_1) willbe (user_2), (user_3)
Is there a way this operation to be realized directly inside MySQL ? if now how it should be solved ?
I have a table which contains student_id, course_id and result. The table structure is as follows
I need to get course_id which the result is 0 and another condition is that the result may not be 1 for that course.
In that image the course_id 633 has both result 0 and 1. so that the particular course_id Do not get from that table.
Regards,
John
I hope this is what you are looking for:
SELECT student_id,course_id,SUM(CASE WHEN result=1 THEN 1 ELSE 0 END) as 0Count
FROM TableName
GROUP BY student_id,course_id
HAVING 0Count=0
SQL Fiddle
Explanation:
Query will returns students with result=0 and who do not have a result=1 for that course.
Sample Output:
student_id course_id result
3061 663 0
3061 663 1
3062 664 1
3063 665 0
The result will be:
STUDENT_ID COURSE_ID 0COUNT
-----------------------------------
3063 664 0
SELECT course_id FROM table_name WHERE result <> 1
edit: unused selections where kicked
Ah I see. I think you are looking for this code
SELECT course_id FROM table_name WHERE result = 0 AND result NOT LIKE "%1%";
Let me know how is it work for you.
Try this query:
SELECT DISTINCT t1.course_id
FROM table_name t1
WHERE t1.result = 0
AND NOT EXISTS (
SELECT 1
FROM table_name t2
WHERE t2.course_id = t1.course_id
AND t2.result = 1);
Try this
SELECT *
FROM TABLE_NAME
WHERE course_id NOT IN
(SELECT course_id
FROM TABLE_NAME
WHERE RESULT=0
AND course_id IN
(SELECT course_id
FROM TABLE_NAME
WHERE RESULT=1))
BEFORE
id | cat_id | order
33 | 1 | 1
34 | 1 | 2
AFTER
id | cat_id | order
33 | 1 | 2
34 | 1 | 1
Now using 4 query
$db is wrap $mysqli for using placeholder and injection defense
get first record by id
$curr = $db->q('SELECT id,order,cat_id FROM `tbl` WHERE id`=? FOR UPDATE',
33)->fetch_assoc();
if exist first record find next record by order field
if($curr){
$next = $db->q('SELECT id,order FROM `tbl` WHERE `cat_id`=? AND
`order`>? ORDER BY `order` LIMIT 1 FOR UPDATE',
$curr['cat_id'],$curr['order']));
if exist first and second recorn change order value
if($prev['id']){
$db->q("UPDATE `tbl` SET `order`=? WHERE `id`=?",$next['order'],$curr['id']);
$db->q("UPDATE `tbl` SET `order`=? WHERE `id`=?",$curr['order'],$next['id']);
}
}
Important! Checking exist two record, lock rows for update
MySQL doesn't support update with the same table in the FROM statement. So because of this there are (select * from TBL) as t2 in inner subqueries.
Also EXISTS condition in the first CASE WHEN is to prevent update if the second record doesn't exists ("if exist first and second records change order value")
Here is a SQLfiddle example
UPDATE tbl as t1
SET `order`=
CASE WHEN id = 33
and
EXISTS (SELECT ID from (select * from TBL) t2 where
cat_id=t1.Cat_Id
and `order`>t1.`order`
ORDER BY `order`
LIMIT 1)
THEN
(SELECT `order` from (select * from TBL) t2 where
cat_id=t1.Cat_Id
and `order`>t1.`order`
ORDER BY `order`
LIMIT 1)
WHEN id <>33 THEN
(SELECT `order` from (select * from TBL) t2 where
cat_id=t1.Cat_Id
and `order`<t1.`order`
ORDER BY `order` DESC
LIMIT 1 )
ELSE `order`
END
where id =33
or
(SELECT ID from (select * from TBL) t2 where
cat_id=t1.Cat_Id
and `order`<t1.`order`
ORDER BY `order` DESC
LIMIT 1) =33
With one query it's:
UPDATE
`tbl`
SET
`order`=CASE
WHEN `order`=2 THEN 1
WHEN `order`=1 THEN 2
END;
WHERE
`order` IN (1,2)
or, for id's condition:
UPDATE
`tbl`
SET
`order`=CASE
WHEN `order`=2 THEN 1
WHEN `order`=1 THEN 2
END;
WHERE
id = $id
To swap 2 fields by row id try:
UPDATE `tbl` AS tbl1
JOIN `tbl` AS tbl2 ON ( tbl1.id = 33 AND tbl2.id = 34 )
SET
tbl1.order = tbl2.order, tbl2.order = tbl1.order
Also you can set your desired value instead of swap between 2 fileds.
If needed, you can add a where clause like below to swap where cat_id are 1 in two rows:
WHERE
tbl1.cat_id = 1 AND tbl2.cat_id = 1
Update:
If your order numbers are unique for any cat_id you can try this way:
UPDATE `tbl` AS tbl1
JOIN `tbl` AS tbl2 ON ( tbl1.order = 1 AND tbl2.order = 2 )
SET
tbl1.order = tbl2.order, tbl2.order = tbl1.order
WHERE
tbl1.cat_id = 1 AND tbl2.cat_id = 1
It works if your order field is int, Otherwise you should quote order values in query.
See the result on SQLFiddle
I have a table with columns:
id name rank rank_pts
1 Nick 0 15
2 N0NE 0 12
3 Non2 0 26
How can I set rank by rank_pts ?
You need a variable.
SET #i= 0;
UPDATE your_table SET rank = (#i:=#i+1) ORDER BY rank_pts;
update your_table
join (SELECT #row:= 0) r
set rank = (#row := #row + 1)
order by rank_pts desc;
Check out this answer to not only rank by rank_pts but how to handle the situation of two rank_pts being the same. Replace score with rank_pts
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