I have the followin problem:
I want to update all rows where COUNT criteria is greater 1, when not I want to update all except 1. It also should update per other_ID.
Dummytable:
+----+----------+----------+-------------+
| id | other_ID | cirteria | updatefield |
+----+----------+----------+-------------+
| 1 | 1 | 1 | 0 |
| 2 | 1 | 1 | 0 |
| 3 | 1 | 1234 | 0 |
| 4 | 2 | 2 | 0 |
| 5 | 2 | 1 | 0 |
| 6 | 2 | 1 | 0 |
| 7 | 4 | 20 | 0 |
| 8 | 4 | 1 | 0 |
| 9 | 4 | 60 | 0 |
| 10 | 5 | 1 | 0 |
| 11 | 5 | 1 | 0 |
| 12 | 6 | 5 | 0 |
+----+----------+----------+-------------+
excpected result:
+----+----------+----------+-------------+
| id | other_ID | cirteria | updatefield |
+----+----------+----------+-------------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 1 |
| 3 | 1 | 1234 | 0 |
| 4 | 2 | 2 | 0 |
| 5 | 2 | 1 | 1 |
| 6 | 2 | 1 | 1 |
| 7 | 4 | 20 | 0 |
| 8 | 4 | 1 | 1 |
| 9 | 4 | 60 | 0 |
| 10 | 5 | 1 | 0 |
| 11 | 5 | 1 | 1 |
| 12 | 6 | 5 | 0 |
+----+----------+----------+-------------+
my idea:
UPDATE pics AS tu SET updatefield=1 WHERE criteria=1 AND (select count(*) as cnt2 from pics where criteria>1 group by other_id)>1;
Error: Table 'tu' is specified twice, both as a target for 'UPDATE' and as a separate source for data
Also I have problems to geht the right count:
SELECT other_id, count() as cnt FROM pics AS ts WHERE criteria=1 and (select count() as cnt2 from pics where criteria>1)>0 GROUP BY other_id;
i want to get cnt = 1 for other_id=5, but i get cnt=2
with
SELECT other_id, COUNT(*) AS cnt2
FROM pics
WHERE criteria>1
GROUP BY other_id;
I get all other_ids where i want to update the updatefield. But how can I connect it with the update? And how to get all except one for other_id=5
You can alias the sub query into another query, e.g.:
UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND other_id IN (
SELECT a.id FROM (
SELECT other_id AS id
FROM test
WHERE criteria > 1
GROUP BY other_id
HAVING COUNT(*) > 1
) a
);
Here's the SQL Fiddle.
Update
This will update the ids for records with criteria 0 and >1. Now, to update the records where there is more than one record with 1 criteria, you need to do something like this:
UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND id IN (
SELECT a.id FROM (
SELECT MIN(id) AS id
FROM test
WHERE criteria = 1
GROUP BY other_id
HAVING COUNT(*) > 1
) a
);
Thanks to #Darshan Mehtas answer and help I finally found the solution to solve it as I want.
Here's the complete solution:
UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND id not IN (
SELECT a.id FROM (
SELECT id
FROM test
WHERE criteria>1
) a
)
AND id not IN (
SELECT b.id FROM (
SELECT id
FROM test
GROUP BY other_id
HAVING COUNT(*) = 1
) b
)
AND id NOT IN (
SELECT c.id FROM (
SELECT id
FROM test
WHERE criteria=1 AND other_id NOT IN (
SELECT other_id FROM test WHERE Criteria>1
)
GROUP BY other_id, criteria
HAVING COUNT(criteria)>1
) c
);
Short description:
First Subquery (a) filters IDs where a criteria is greater 1
Second Subquery (b) filters IDs which have only on result
Third Subquery (c) filters IDs Where criteria is 1an don't have any higher criteria and keeps, thansk grouping, the first result.
Only bad thing could be to keep in the last subquery (c) the first (mostly oldest) result instead of newest.
€dit:
to keep the last result use this for subquery c instead:
AND id NOT IN (
SELECT c.id FROM (
SELECT id
FROM test t1
JOIN (SELECT other_id, max(id) maxid
FROM test
GROUP BY other_id) t2
ON t1.otheR_id=t2.other_id AND t1.id=t2.maxid
WHERE criteria=1 AND t1.other_id NOT IN (
SELECT other_id FROM test WHERE Criteria>1
)
GROUP BY t1.other_id, criteria
) c
);
Related
I have the following employee_sequence table
| id | employee_id | sequence_id | is_completed |
|----|:-----------:|:-----------:|:------------:|
| 1 | 12 | 3 | 1 |
| 2 | 12 | 4 | 1 |
| 3 | 10 | 3 | 1 |
| 4 | 10 | 4 | 0 |
I am looking for how to get, in 1 query, the first row having is_completed = 0 for an employee. If no such row for that employee, then take first row having is_completed = 1
Example for employee_id = 12 (there is no is_completed = 0, so first row having is_completed = 1)
| id | employee_id | sequence_id | is_completed |
|----|:-----------:|:-----------:|:------------:|
| 1 | 12 | 3 | 1 |
Example for employee_id = 10 (first row having is_completed = 0)
| id | employee_id | sequence_id | is_completed |
|----|:-----------:|:-----------:|:------------:|
| 4 | 10 | 4 | 0 |
You can use row_number(), if yu are running MySQL 8.0; assumuming that id can be used to order the records, you would phrase this as:
select *
from (
select es.*, row_number() over(partition by employee_id order by is_completed, id) rn
from employee_sequence es
) es
where rn = 1
In ealier version, an alternative is a correlated subquery with a row-limiting clause:
select *
from employee_sequence es
where es.id = (
select es1.id
from employee_sequence es1
where es1.employee_id = es.employee_id
order by es1.is_completed, es.id
limit 1
)
If you want this per employee (as your question suggests):
select es.*
from employee_sequence es
where es.employee_id = 12
order by is_completed, id
limit 1;
Here is a db<>fiddle.
If you are running something less than MySql 8 then:
select * from employee_sequence e1
where e1.id = (
select e2.id
from employee_sequence e2
where e2.employee_id = e1.employee_id
order by e2.is_completed, e2.sequence_id
limit 1
);
| id | employee_id | sequence_id | is_completed |
| --- | ----------- | ----------- | ------------ |
| 1 | 12 | 3 | 1 |
| 4 | 10 | 4 | 0 |
View on DB Fiddle
Sample Data:
id | room_id | seat_num
----------------------------------
1 | 1 | null
2 | 1 | null
3 | 2 | null
4 | 2 | null
Desire Data:
id | room_id | seat_num
----------------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 2
how to write a sql to update the room seat number to serial num in MySQL 5.7? the room's seat is from 2-20.
One option uses the update/join syntax. In MySQL 5.7, where window functions are not available, you can emulate row_number() with a correlated subquery (which is somehow safer than user variables):
update mytable t
inner join (
select id,
(select count(*) from mytable t1 where t1.room_id = t.room_id and t1.id <= t.id) rn
from mytable t
) t1 on t1.id = t.id
set t.seat_num = t1.rn
Demo on DB Fiddle:
id | room_id | seat_num
:- | ------: | :-------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 1
4 | 2 | 2
I have two tables.
I want to select 1 record from first table if
condition is true in second table (active = 0)
table Lead:
-------------
| id | name |
-------------
| 1 | abc1 |
| 2 | abc2 |
| 3 | abc3 |
| 4 | abc4 |
| 5 | abc5 |
-------------
table LeadsDetails:
-------------------------
| id | lead_id | active |
-------------------------
| 1 | 1 | 1 |
| 2 | 1 | 0 |
| 3 | 2 | 0 |
| 4 | 3 | 1 |
| 5 | 4 | 0 |
| 6 | 5 | 0 |
| 7 | 5 | 0 |
--------------------------
expected output:
--------------
| id | name |
--------------
| 2 | abc2 |
| 4 | abc4 |
| 5 | abc5 |
--------------
SELECT `Lead`.`id`, `Lead`.`name`, `Lead`.`unsubscribe`
FROM `leads` AS `Lead` inner JOIN `LeadsDetails` AS `LeadsDetails`
ON (`LeadsDetails`.`lead_id` = `Lead`.`id`)
WHERE `LeadsDetails`.`active` = 0
This should run faster than not exists because the subquery won't run for every row; in this case I'm counting the number of situations where the active field value on table leadsdetails is not 0, for the given ID, and showing only rows where that count is 0 (ie. for the given id the active field is ALWAYS 0)
select l.id, l.name
from lead l
join leadsdetails ld
on l.id = ld.lead_id
group by l.id, l.name
having sum(case when ld.active <> 0 then 1 else 0 end) = 0
Fiddle: http://www.sqlfiddle.com/#!2/00970/2/0
As you need to get the records only when active column doesn't have 1
use NOT EXISTS
SQL FIDDLE DEMO : http://www.sqlfiddle.com/#!2/00970/1
SELECT * FROM
Lead L
WHERE NOT EXISTS (
SELECT 1 FROM LeasdDetails LD
where L.id = LD.lead_id
AND LD.active =1
)
I think you can do what you want with an exists clause:
select l.*
from Lead l
where exists (select 1 from LeadsDetails ld where ld.lead_id = l.id and ld.active = 0)
i wonder if someone could help me out with this problem.
I'd like to update the column "result" in TABLE1 SET "1" when all to the ID(TABLE1) belonging tab1ID-values have in column result the value 1.
The ID in table1 are in relationship with tab1ID in table2. Hope this will make it clear:
Table1:
id | result |
1 | null |
2 | null |
3 | null |
Table2:
id | tab1ID | result |
1 | 1 | 1
2 | 1 | 0
3 | 1 | 1
4 | 2 | 1
5 | 2 | 1
6 | 2 | 1
7 | 3 | 0
8 | 3 | 1
9 | 3 | 1
The UPDATE-Satement should now UPDATE TABLE1 like this:
Table1:
id | result |
1 | 0 |
2 | 1 |
3 | 0 |
result at ID2 is 1 now, because all the belonging tab1ID (2) rows in table2 have the result-value 1
How can i do this with one update-statement?
This query assumes that the values for Table2.Result are only 1 and 0.
UPDATE table1 a
INNER JOIN
(
SELECT tab1ID, COUNT(*) = SUM(result) result
FROM table2
GROUP BY tab1ID
) b ON a.ID = b.tab1ID
SET a.result = b.result
SQLFiddle Demo
How to select 1st, 2nd or 3rd value before MAX ?
usually we do it with order by and limit
SELECT * FROM table1
ORDER BY field1 DESC
LIMIT 2,1
but with my current query I don't know how to make it...
Sample table
+----+------+------+-------+
| id | name | type | count |
+----+------+------+-------+
| 1 | a | 1 | 2 |
| 2 | ab | 1 | 3 |
| 3 | abc | 1 | 1 |
| 4 | b | 2 | 7 |
| 5 | ba | 2 | 1 |
| 6 | cab | 3 | 9 |
+----+------+------+-------+
I'm taking name for each type with max count with this query
SELECT
`table1b`.`name`
FROM
(SELECT
`table1a`.`type`, MAX(`table1a`.`count`) AS `Count`
FROM
`table1` AS `table1a`
GROUP BY `table1a`.`type`) AS `table1a`
INNER JOIN
`table1` AS `table1b` ON (`table1b`.`type` = `table1a`.`type` AND `table1b`.`count` = `table1a`.`Count`)
and I want one more column additional to name with value before max(count)
so result should be
+------+------------+
| name | before_max |
+------+------------+
| ab | 2 |
| b | 1 |
| cab | NULL |
+------+------------+
Please ask if something isn't clear ;)
AS per your given table(test) structure, the query has to be as follows :
select max_name.name,before_max.count
from
(SELECT type,max(count) as max
FROM `test`
group by type) as type_max
join
(select type,name,count
from test
) as max_name on (type_max.type = max_name.type and count = type_max.max )
left join
(select type,count
from test as t1
where count != (select max(count) from test as t2 where t1.type = t2.type)
group by type
order by count desc) as before_max on(type_max.type = before_max .type)