I have the following little bit of MySQL code
CREATE VIEW UserResults AS
SELECT E.No, E. Description
, Count(R.RID WHERE $Username= R.Owner)
, Count(R.RID WHERE $Username= R.Owner AND Status==’Active’ )
FROM ETable AS E, RTABLE as R
ORDER BY E.No)
but MySQL is returning a syntax error that I can't seem to find. Also when I have created this view, how can I make it viewable?
You have an extra ending parenthesis, which should be removed
Views should not have ORDER BY.
The WHERE clause should not be in the middle of the SELECT, you will need to use a CASE.
You are returning a Cartesian product instead of joining your tables together, this may provide more results than you want/expect.
The R.RID in the THEN block of the CASE statements may need to be a 1, not entirely sure what you hoped to get from those COUNT statements you originally had.
I tried to figure out what you were trying to do, and I think this is it:
CREATE VIEW UserResults AS
SELECT E.No, E.Description
, SUM(CASE
WHEN $Username = R.Owner THEN R.RID
ELSE 0
END) AS SumOfOwner
, SUM(CASE
WHEN $Username = R.Owner AND Status = 'Active' THEN R.RID
ELSE 0
END) AS SumOfOwnerAndActive
FROM ETable AS E
INNER JOIN RTABLE as R ON E.No = R.ENo
GROUP BY E.No, E.Description
The Subquery which you create the view from is wrong:
SELECT E.No, E. Description, Count(R.RID WHERE $Username= R.Owner), Count(R.RID WHERE $Username= R.Owner AND Status==’Active’ ) FROM ETable AS E, RTABLE as R ORDER BY E.No)
you can not use where inside a count like:
Count(R.RID WHERE $Username= R.Owner)
Take a look at the Documentation and check the syntax again.
and try to replace the Status == 'Active' with Status = 'Active'
Once you created the view you can read it normally like a table usign the select keyword
As well as other issues identified in other answers, you need to specify the names of the columns in the view with:
CREATE VIEW UserResults(No, Description, UserCount, ActiveCount) AS ...
Also, in classic (standard) SQL, you cannot parameterize a view with a variable; the $Username notation looks like a parameter - and would not be allowed, therefore.
Related
When I run the below SQL statement, it correctly shows me what I expect:
SELECT Users.idQuiz as ThisIDQuiz,Rounds.RoundNr as ThisRoundNr, Questions.QuestionNr as ThisQuestionNr, Answer as ThisAnswer, Questions.QuestionScore AS QuestionScoreMax,AnswerCorrect,
(SELECT COUNT(*) as "Aantal Ploegen met dit antwoord"
FROM `Answers`
JOIN Questions on Answers.idQuestion = Questions.idQuestion
JOIN Rounds on Questions.idRound = Rounds.idRound
JOIN Users on Users.idUser = Answers.idUser
where (Users.idQuiz = ThisIDQuiz AND Rounds.RoundNr = ThisRoundNr AND Questions.QuestionNr=ThisQuestionNr AND Answers.Answer = ThisAnswer )
GROUP BY Users.idQuiz,Rounds.RoundNr, Questions.QuestionNr,Answer
) as NrOfTeamsWithThisAnswer,
(SELECT COUNT(*)
FROM Users
WHERE ((Users.idQuiz = ThisIDQuiz) AND (Users.UserType = 0))
) As TotalNrOfTeams,
AnswerCorrect *((Select TotalNrOfTeams)- (SELECT NrOfTeamsWithThisAnswer))as ScoreForThisAnswer
FROM `Answers`
JOIN Questions on Answers.idQuestion = Questions.idQuestion
JOIN Rounds on Questions.idRound = Rounds.idRound
JOIN Users on Users.idUser = Answers.idUser
WHERE Questions.QuestionType = 5
GROUP BY ThisAnswer
ORDER BY ThisIDQuiz, ThisRoundNr, ThisQuestionNr, ThisAnswer;
See Results of the query for what the result looks like.
I then create a VIEW from this statement. The view is created fine, but when I open it, I get the error "#1242 - Subquery returns more than 1 row".
I tried dropping and recreating the view, same result.
When I use the exact same SQL statement but without the penultimate line (GROUP BY ThisAnswer), it works fine (i.e. I can create the view and it opens without an error). This second view suits my purposes fine, so I can continue, but just out of curiosity: can someone explain this behaviour?
I use phpMyAdmin version 5.1.3 to do my SQL manipulations.
As #NickW asks, the statement GROUP BY ThisAnswer expects you to have an aggregate function (i.e. count, avg, max, min, etc.) somewhere in that main SELECT. Having a GROUP BY without an aggregate function will create errors. Either add the aggregate function, or remove the GROUP BY statement in the main (outermost) SELECT.
I've got a products table that I'm trying to get to work. The query brings back results; however, it isn't actually using the ORDER BY FIELD to sort the results. It's skipping it somehow. I even tried ORDER BY FIELD(sc.id,'4','5','6'), and that didn't work either.
Is it even possible to use table_name.column in an ORDER BY FIELD()? Is there an alternative or a better method of doing this query?
$product = $db1q->query("
SELECT p.id, p.name, p.image, p.url,p.subcat as subcat, sc.id as scid,sc.name as scname
FROM Product as p
JOIN Product_Sub_Category as sc ON p.subcat = sc.id
WHERE p.visibility='1' AND find_in_set(p.id,'". $sidr['products'] ."')
ORDER BY FIELD(p.subcat,'4','5','6'), sc.sort_order ASC, p.sort_order ASC")
or die ('Unable to execute query. '. mysqli_error($db1q));
I just dumbed the query down to the basic level....
$product = $db1q->query("
SELECT id, name, image, url,subcat
FROM Product WHERE visibility='1' AND id IN ({$sidr['products']}) ORDER BY FIELD(subcat,'5','4','6','22')") or die ('Unable to execute query. '. mysqli_error($db1q));
and for some reason the order of my subcats are as follows....
3,12,23,5,5,4,4,4,4,4,22
Why wouldn't they begin with 5, 4, 6(doesn't exist), and 22? Then display 3,12, and 23 after those are first....
Simple Rextester Demo
When datatype is numeric don't compare to 'string' values
eg visibility = '1' if visibility is numeric you really shouldn't have the apostrophes around it. same in the field function given subcat.
$product = $db1q->query("SELECT id, name, image, url,subcat
FROM Product
WHERE visibility='1'
AND id IN ({$sidr['products']})
ORDER BY case when subcat in (5,4,6,22) then 0 else 1 end,
FIELD(subcat,5,4,6,22)
") or die ('Unable to execute query. '. mysqli_error($db1q));
or something like:
order by case when field(sort,'5','4','22') = 0 then (select max(sort)+1+sort from Product)
else field(sort,'5','4','22') end;
The issue with the 2nd approach is that it has to run a subquery for every record. In addition if the size of subcat/sort exceed or approach the max of int we'll run into a problem adding the values together. This problem is negated by using the 2 column sort approach in the first method.
Again, my gut feeling is that the first approach with 2 sort columns would be faster; and in my opinion easier to follow/maintain. The downfall is if the sort order defined changes then we have to change code. So... why have the order defined here... what isn't the order defined in a table; or is the order passed in as a parameter by user?
I have a MySQL query and I need to SUM the content of a column if the content contains the number 1,
This is what I have but the TotalFails returns 0
SELECT
d.SeqNo,
d.SeqText,
h.UniqueID,
h.SeqID,
h.Room,
IF(h.Status = '1', SUM(h.Status), 0) AS TotalFails
FROM ".$SequenceNo_default." d
LEFT
JOIN ".$Hist." h ON h.SeqID = d.SeqID
WHERE d.SeqActive = 1 AND DATE(CompStamp) BETWEEN DATE( '".$_SESSION['StartDate']."') AND DATE('".$_SESSION['EndDate']."')
GROUP BY h.Room
ORDER BY h.Status ASC
Can any one see where I am going wrong?
Please note that Status is a reserved keyword so you may want to change it to something else like myStatus in the statement above.
Edit
Based upon your updated question, I would rewrite your query as follows (again, avoiding the keyword STATUS by replacing Status with myStatus):
SELECT
d.SeqNo,
d.SeqText,
h.UniqueID,
h.SeqID,
h.Room,
SUM(h.myStatus) AS TotalFails
FROM ".$SequenceNo_default." d
LEFT
JOIN ".$Hist." h ON h.SeqID = d.SeqID
WHERE d.SeqActive = 1 AND DATE(CompStamp) BETWEEN DATE( '".$_SESSION['StartDate']."') AND DATE('".$_SESSION['EndDate']."')
GROUP BY h.Room, h.myStatus
ORDER BY h.myStatus ASC
As a separate side note, this should be a prepared query, rather than including the $_SESSION variable directly into the string. $_SESSION is better than $_POST or $_GET, but for maintaining the code, this would be a good habit (for example, what if the code later changes to $_POST?).
Here is a brief explanation of what I'm trying to accomplish; my query follows below.
There are 4 tables and 1 view which are relevant for this particular query (sorry the names look messy, but they follow a strict convention that would make sense if you saw the full list):
Performances may have many Performers, and those associations are stored in PPerformer. Fans can have favorites, which are stored in Favorite_Performer. The _UpcomingPerformances view contains all the information needed to display a user-friendly list of upcoming performances.
My goal is to select all the data from _UpcomingPerformances, then include one additional column that specifies whether the given Performance has a Performer which the Fan added as their favorite. This involves selecting the list of Performers associated with the Performance, and also the list of Performers who are in Favorite_Performer for that Fan, and intersecting the two arrays to determine if anything is in common.
When I execute the below query, I get the error #1054 - Unknown column 'up.pID' in 'where clause'. I suspect it's somehow related to a misuse of Correlated Subqueries but as far as I can tell what I'm doing should work. It works when I replace up.pID (in the WHERE clause of t2) with a hard-coded number, and yes, pID is an existing column of _UpcomingPerformances.
Thanks for any help you can provide.
SELECT
up.*,
CASE
WHEN EXISTS (
SELECT * FROM (
SELECT RID FROM Favorite_Performer
WHERE FanID = 107
) t1
INNER JOIN
(
SELECT r.ID as RID
FROM PPerformer pr
JOIN Performer r ON r.ID = pr.Performer_ID
WHERE pr.Performance_ID = up.pID
) t2
ON t1.RID = t2.RID
)
THEN "yes"
ELSE "no"
END as pText
FROM
_UpcomingPerformances up
The problem is scope related. The nested Selects make the up table invisible inside the internal select. Try this:
SELECT
up.*,
CASE
WHEN EXISTS (
SELECT *
FROM Favorite_Performer fp
JOIN Performer r ON fp.RID = r.ID
JOIN PPerformer pr ON r.ID = pr.Performer_ID
WHERE fp.FanID = 107
AND pr.Performance_ID = up.pID
)
THEN 'yes'
ELSE 'no'
END as pText
FROM
_UpcomingPerformances up
I'm receieving the following error:
[Err] 1349 - View's SELECT contains a subquery in the FROM clause
When creating this view:
create view v_rescume_info as
select((case when goods.goods_fee is null then 0 else goods.goods_fee end)
+(case when rent.rent_fee is null then 0 else rent.rent_fee end)
+(case when baoxiao.baoxiao_fee is null then 0 else baoxiao.baoxiao_fee end))
as rescume_fee,goods.member_id from (select sum(product_price * product_quantity) as goods_fee,member_id from product_general_info group by member_id) goods
left join (select sum(house_fee + (case when water_fee is null then 0 else water_fee end)*water_price
+(case when electric_fee is null then 0 else electric_fee end)*electric_price) rent_fee,member_id from member_rent_info group by member_id) rent
on goods.member_id = rent.member_id
left join (select sum(finishedoff_price) as baoxiao_fee ,member_id from member_finishedoff_info group by member_id) baoxiao
Well that's a mess.
In order to help you, you can replace those "cases when... then" with coalesce
create view v_rescume_info as
select(
Coalesce(goods.goods_fee,0) + Coalesce(rent.rent_fee, 0) +
Coalesce(baoxiao.baoxiao_fee,0) as rescume_fee,
goods.member_id from v_newView1
Why I put the v_newView here? Well.. you are really trying to select from another select. You can cross tables but it never worked for me this way. This looks like Transact-SQL rather than MySQL sintax.
Before you create views, please test those views outside. You only should put "Create View foo as " once you got the results working.
For what I can see, you need to create another view, "my" v_newView1 in order to get the results from a sub-query. I recommend you to use the join functions (left, right, inner) to achieve what you intend.
Without the database it's hard to figure where is your problem. Also use multiple lines while debugging. It really helps to see where witch line is producing your error.