Update values that have something in common - mysql

I´m trying to set a value for those pets who share a owner.
update Pets
set multiple = 1
where Phone_owner in (
SELECT *
FROM (
SELECT Phone_owner, COUNT(*) Total
FROM Pets
GROUP BY Phone_owner
HAVING COUNT(*) > 1
) a
);
I get this error:
Error Code: 1241. Operand should contain 1 column(s)

Use a JOIN rather than WHERE ... IN
UPDATE Pets AS p1
JOIN (
SELECT Phone_owner
FROM Pets
GROUP BY Phone_owner
HAVING COUNT(*) > 1
) AS p2 ON p1.Phone_owner = p2.Phone_owner
SET p1.multiple = 1

Related

Get all applications where count of positions more then 1

I have 2 tables
LoanApplications (Id, Name, CreationDate, LoanApplicationStatusId)
Positions(Id, Name, CreationDate, LoanApplicationId)
I need to find all loan applications that have more than 1 position and update LoanApplicationStatusId to 2
I write code to get these LoanApplications like this
SELECT e.Id, count(Name) FROM LoanApplications e
INNER JOIN Positions d ON e.Id=d.LoanApplicationId
GROUP BY e.Id
HAVING COUNT(Name)>1
But I don't understand how to make an update now.
Can you help me?
Straight ahead would be a simple subselect
UPDATE LoanApplications l
SET LoanApplicationStatusId = 2
where (select count(1) from Positions p where p.LoanApplicationId = l.id) > 1
Simply select id of apps which have more than one row, and use it in UPDATE as a condition
UPDATE LoanApplications
JOIN ( SELECT LoanApplicationId
FROM Positions
GROUP BY LoanApplicationId
HAVING COUNT(LoanApplicationId) > 1 ) multi_positional ON id = LoanApplicationId
SET LoanApplicationStatusId = 2
Unsafe query: 'Update' statement without 'where' updates all table rows at once Got this stuff – Eugene Sukh
Convert this query to
UPDATE LoanApplications
JOIN ( SELECT LoanApplicationId
FROM Positions
GROUP BY LoanApplicationId
HAVING COUNT(LoanApplicationId) > 1 ) multi_positional
SET LoanApplicationStatusId = 2
WHERE LoanApplications.id = multi_positional.LoanApplicationId

MySql throws error Subquery returns more than 1 row

I want to retrieve values from 3 table where i am getting error "Sub query returns more than 1 row " .
My concept is to retrieve all the post where i have to calculate the sum of votes from ttpostvotes table with respect to each post and if provided userid is voted for the that post then it will shows the post count like 1 or -1.
My query is as below:
SELECT r.PostId, r.`Post`,r.PostTime, coalesce(x.Votes, 0) as Votes ,
(Select Votes From `ttpostvotes` where UserId=30 and x.PostId=r.PostId ) as IsUservoted,
(Select Count(*) From ttreply where PostId=r.PostId ) AS ReplyCount FROM `ttpost` r
left join ( SELECT PostId, sum(Votes) as Votes FROM `ttpostvotes` GROUP BY PostId ) x ON
x.PostId = r.PostId WHERE r.OffensiveCount<3 and r.SpamCount<5 and r.OtherCount<7 and r.`PeekId`=101 ORDER BY `r`.`PostTime` DESC
The 3 tables are like as below:
ttpost
ttpostvotes
ttreply
This is your select:
SELECT r.PostId, r.`Post`,r.PostTime, coalesce(x.Votes, 0) as Votes,
(Select Votes From `ttpostvotes` where UserId = 30 and x.PostId = r.PostId
) as IsUservoted,
(Select Count(*) From ttreply where PostId=r.PostId ) AS ReplyCount
The first subquery has no aggregation, so I suppose a user could vote more than once for a post. This will fix the syntax error:
SELECT r.PostId, r.`Post`,r.PostTime, coalesce(x.Votes, 0) as Votes,
(Select SUM(Votes) From `ttpostvotes` where UserId = 30 and x.PostId = r.PostId
) as IsUservoted,
(Select Count(*) From ttreply where PostId = r.PostId ) AS ReplyCount
Whether it does what you want is a different question.
Note: if you want your original query to work, you should define a unique constraint/index on ttpostvotes:
create unique index unq_ttpostvotes_userid_postid on ttpostvotes(userid, postid);

mysql SELECT EXISTS on multiple tables

Have tables: person,person_ip
Both tables have pid column as a primary key, in table person there is column state_id, in table person_ip there is column ip.
Want to discover if specified IP address is assigned to person with state_id is not equal to 2. But always got result 1, even if state_id is 0, 1 or 2. Always got 0 only if ip address is not listed at all. What am I doing wrong?
SELECT EXISTS (
SELECT person_ip.PID
FROM person_ip,person
WHERE person.PID=person_ip.PID
AND person.state_id NOT IN (2)
AND person_ip.ip='10.11.12.13'
)
this seems like a simple join.. unless i'm missing something
select person.*
from person
inner join person_ip
on person.pid = person_ip.pid
where person.state_id <> 2
and person_ip.ip_address = '10.0.0.1'
If you want to exclude the ip_address if it has been assigned to any user with state = 2, even if it has also been assigned to a user without state = 2, then try:
select max(i)
from (
select *
from (
select 1 as i
from dual
where not exists (
select 1
from person p
inner join person_ip pi
on p.pid = pi.pid
where p.state_id = 2
and pi.ip_address = '10.0.0.1'
)
) q
union
select 0
) qq
(dual is a system table that can be used as a sort of stub table)
here's a fiddle showing both versions
update after some actual sleep
Okay, so the above query is a little.. out there. Back in the real world, this one is probably more appropriate:
select count(case when p1.state_id = 2 then 1 end)
from person p1
inner join person_ip pi1
on p1.pid = pi1.pid
where pi1.ip_address = '10.0.0.1'
group by pi1.ip_address;
This will return 1 or more if your ip_address has been used by someone with a state_id of 2, and 0 if it has never been used by someone with a state_id of 2.
It will return nothing if the ip has never been used.
this fiddle has all three of the above queries.
SELECT IF(COUNT(*)>0,1,0)
FROM person
INNER JOIN person_ip
ON person.pid = person_ip.pid
AND person_ip.ip_address = '10.0.0.1'
WHERE person.state_id <> 2

Pivot result returning duplicate rows

With this query, I am getting result with null values and duplicate Ids...
SELECT QuesId,QuesName,[Ketan Mevada],[Parvej],[Parvez Vahora]
FROM (
SELECT tbl_EvolutionAnswer.QuesId,tbl_QuestionMaster.Name as QuesName,
dbo.Evaluation_Calculation_CourseWise(tbl_EvolutionAnswer.QuesId,34,'Course-Green Course-2045',1065, tbl_EvolutionAnswer.TrainerId ) as Average,
tbl_EvolutionAnswer.TrainerId,
tbl_TrainerMaster.Name as TrName
from tbl_EvolutionAnswer
inner join tbl_TrainerMaster
on tbl_EvolutionAnswer.TrainerId = tbl_TrainerMaster.Id
inner join tbl_QuestionMaster
on tbl_EvolutionAnswer.QuesId = tbl_QuestionMaster.QuestionId
where tbl_EvolutionAnswer.EvolId =34
and tbl_EvolutionAnswer.TrainerId <> 0
and tbl_EvolutionAnswer.CourseId = 'Course-Green Course-2045'
and tbl_EvolutionAnswer.SchID = 1065
) as Books
PIVOT (
MAX(Average) FOR TrName IN ([Ketan Mevada],[Parvej],[Parvez Vahora])
) as Result
I need Following Output
QuesId QuesName Ketan Mevada Parvej Parvez Vohra
122 Did your trainer answer... 2 3 2
123 was your trainer activ.. 1 4 3
It appears that you have a column inside your subquery that is unique and it is causing the grouping of the aggregate function to be skewed. When you are using the PIVOT function, you should only include the columns needed for the PIVOT and the final select list, otherwise you run the risk of the end result being spilt over multiple rows.
It looks like the column you need to remove is tbl_EvolutionAnswer.TrainerId. Making your actual query:
SELECT QuesId,QuesName,[Ketan Mevada],[Parvej],[Parvez Vahora]
FROM
(
SELECT tbl_EvolutionAnswer.QuesId,
tbl_QuestionMaster.Name as QuesName,
dbo.Evaluation_Calculation_CourseWise(tbl_EvolutionAnswer.QuesId,34,'Course-Green Course-2045',1065, tbl_EvolutionAnswer.TrainerId ) as Average,
tbl_TrainerMaster.Name as TrName
from tbl_EvolutionAnswer
inner join tbl_TrainerMaster
on tbl_EvolutionAnswer.TrainerId = tbl_TrainerMaster.Id
inner join tbl_QuestionMaster
on tbl_EvolutionAnswer.QuesId = tbl_QuestionMaster.QuestionId
where tbl_EvolutionAnswer.EvolId =34
and tbl_EvolutionAnswer.TrainerId <> 0
and tbl_EvolutionAnswer.CourseId = 'Course-Green Course-2045'
and tbl_EvolutionAnswer.SchID = 1065
) as Books
PIVOT (
MAX(Average) FOR TrName IN ([Ketan Mevada],[Parvej],[Parvez Vahora])
) as Result

SQL Comparing 2 values that must be determined

I need to Find out the course with the most passes from my table tblResults.
tblResults:
StuID Course Symbol
1001 CSC101 P
1001 RNG101 F
1002 CSC101 P
1002 RNF101 F
1003 HAP101 P
1004 HAP101 P
i.e should give CSC101 (And all other courses (HAP101) with the same ammount of passes)
I have tried:
CREATE VIEW Part1 AS
SELECT NumbF
FROM
(SELECT COUNT(Course) AS NumbP,
Course
FROM tblResults
WHERE Symbol = 'P')
GROUP BY Course);
CREATE VIEW Part2 AS
SELECT MAX(NumbP) AS Maxnum
FROM Part1,
tblResults
WHERE Symbol = 'P'
GROUP BY Course;
SELECT Part1.Course
FROM Part1,
Part2
WHERE Part1.NumbP = Part2.MaxNum
But I seem to be doing something incorrectly. Please help
Something like this should work:
create view yourview as
select course, count(*) passcnt
from tblResults
where symbol = 'P'
group by course
select *
from yourview
where passcnt = (select max(passcnt) from yourview)
SQL Fiddle Demo
Note, you don't need the view, I just left it for simplicity.
SELECT Course, count(StuID) count
FROM tblResults
GROUP BY Course
HAVING count = (SELECT max(c)
FROM (SELECT count(StuID) c, Course
FROM tblResults
GROUP BY Course
WHERE Symbol = 'p'
) counts
);
You can try the SELECT below, but I haven't tested it:
SELECT selA.Course, selA.NumPass FROM (
SELECT Course, COUNT(Course) AS NumPass FROM
tblResults GROUP BY Course HAVING Symbol = 'P') AS selA
INNER JOIN (
SELECT MAX(NumPassCount) AS NumPassMax FROM (
SELECT COUNT(Course) AS NumPassCount FROM
tblResults GROUP BY Course HAVING Symbol = 'P') AS selB)
AS selC ON selA.NumPass = selC.NumPassMax
Using a couple of sub queries
SELECT Sub3.Course
FROM
(
SELECT MAX(Course) AS MaxCourseCnt
FROM
(
SELECT Course, COUNT(*) AS CourseCnt
FROM tblResults
WHERE Symbol = 'P'
GROUP BY Course
) Sub1
) Sub2
INNER JOIN
(
SELECT Course, COUNT(*) AS CourseCnt
FROM tblResults
WHERE Symbol = 'P'
GROUP BY Course
) Sub3
ON Sub2.MaxCourseCnt = Sub3.CourseCnt