BOOK_ADOPTION (course:int, sem:int, book_isbn:int)
TEXT (book_isbn:int, booktitle: varchar(50), publisher: varchar(50), author: varchar(50))
List the books which are adopted by the course as well as enrolled by the student.
I am trying this:
select course
from text
natural join book_adoption
group by course
having count(book_isbn)>1
and publisher = 'perason';
and getting an error:
Unknown column 'publisher' in 'having clause'
but the column publisher is there and even the spelling is correct.
Can someone help me out with this one?
HAVING clause is for using with aggregating functions (like count) but in the case of publisher you have to simply use the WHERE condition.
select course
from text natural join book_adoption
where publisher = 'perason'
group by course
having count(book_isbn)>1;
Related
hi I'm just starting to learn sql and I wish to combine the columns into one using concat but didn't manage to do it. I can run the code without concat but when when I use concat it gives me an error code. Can anyone tell me what am I doing wrong?
SELECT CONCAT('A purchase with the purchase ID of' AS "Constraint",
ONLINEPURCHASE.PurchaseID AS "OLID", 'is an online purchase of type' AS "Condition", ONLINEPURCHASE.OnlineType AS "OLType", 'and also a walkin purchase of location' AS "Condition", WALKINPURCHASE.ShopLocation AS "ShopLocation")
FROM ONLINEPURCHASE JOIN WALKINPURCHASE
ON ONLINEPURCHASE.PurchaseID = WALKINPURCHASE.PurchaseID
WHERE WALKINPURCHASE.PurchaseID IN (SELECT PurchaseID
FROM WALKINPURCHASE);
But got this error (ERROR 1583 (42000): Incorrect parameters in the call to native function 'concat')
Congratulations on starting to learn SQL, it's super useful! Let me try to clear up your misunderstanding.
The CONCAT function takes some number of either strings or column values and joins them together. There's no need to use the AS keyword within it.
Here's what I think you're looking for:
SELECT
CONCAT(
'A purchase with the purchase ID of',
ONLINEPURCHASE.PurchaseID,
'is an online purchase of type',
ONLINEPURCHASE.OnlineType,
'and also a walkin purchase of location',
WALKINPURCHASE.ShopLocation
) AS result
FROM ONLINEPURCHASE JOIN WALKINPURCHASE
ON ONLINEPURCHASE.PurchaseID = WALKINPURCHASE.PurchaseID
WHERE WALKINPURCHASE.PurchaseID IN
(SELECT PurchaseID FROM WALKINPURCHASE);
This will create the sentence you're building in the CONCAT statement and return it as a single column of your result set. (I've used the AS keyword to rename the column you've built.)
Please let me know if you have any questions about this.
I have troubles with execution sql
any time I execute it gives me an error Ambiguous column name 'salesYTD'
my statement is :
SELECT COUNTRYREGIONCODE, NAME, AVG(SALESQUOTA),AVG(BONUS), AVG(SALESYTD)
FROM SALES.SALESPERSON SP
INNER JOIN SALES.SALESTERRITORY ST
ON SP.TERRITORYID = ST.TERRITORYID
GROUP BY NAME, COUNTRYREGIONCODE;
the name of that column is correct. I don't understand what I am doing wrong. Thanks for any help
This means that SALESYTD is in both tables. I don't know which you want.
When you have more than one table in a query always qualify your column names.
SELECT ST.NAME, ST.COUNTRYREGIONCODE,
AVG(SP.SALESQUOTA), AVG(SP.BONUS), AVG(SP.SALESYTD)
FROM SALES.SALESPERSON SP INNER JOIN
SALES.SALESTERRITORY ST
ON SP.TERRITORYID = ST.TERRITORYID
GROUP BY ST.NAME, ST.COUNTRYREGIONCODE;
I'm just guessing where the columns come from.
Does that column exist in more than one table?
If so, you should name the field like this:
SP.salesYTD
or
ST.salesYTD
Depending on what you want to show.
Good luck.
i am using mysql version 5.7.13 in linux
When i running the stored procedure i am getting the following error
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause
and contains nonaggregated column 'medigurus.pp.physicianid' which is not
functionally dependent on columns in GROUP BY clause; this is
incompatible with sql_mode=only_full_group_by
My Procedure is
DELIMITER $$ DROP PROCEDURE IF EXISTS medigurus.getPatientDoctors$$ CREATE
DEFINER=root#localhost PROCEDURE getPatientDoctors(IN patientid INT(10))
BEGIN SELECT pp.physicianid, d.physiciantypeid, p.firstname, p.lastname,
p.dob, p.mobile, p.officephone, p.address1, p.address2, p.city, p.stateid,
p.cid, p.zip,p.speciality, p.about, p.imgid FROM patientphysicians pp INNER
JOIN physician p ON pp.physicianid = p.physicianid INNER JOIN
getpatientdoctorsview AS d ON d.patientid=pp.patientid WHERE pp.patientid
= patientid GROUP BY p.physicianid; END$$ DELIMITER ;
and view is
DELIMITER $$
DROP VIEW IF EXISTS `medigurus`.`getpatientdoctorsview`$$
CREATE ALGORITHM=UNDEFINED
DEFINER=`root`#`localhost` SQL SECURITY DEFINER VIEW `getpatientdoctorsview` AS
select `pp`.`physicianid` AS `physicianid`,`pp`.`patientid` AS
`patientid`,group_concat(`pp`.`physiciantypeid` separator ',') AS
`physiciantypeid`
from `patientphysicians` `pp` group by `pp`.`patientid`$$
DELIMITER ;
How can i fix the error..
A quick solution is to apply an aggregate function to medigurus.pp.physicianid, like this:
select ... min(medigurus.pp.physicianid) as physicianid, ...
The reason for the error message is that medigurus.pp.physicianid is ambiguous as there could be several values per group, and the SQL engine would need to pick one. Without this setting (restriction), it would just take the first one it encounters, but that behaviour is not in line with the SQL standards.
However, by indicating which one of these values you want to return (e.g. via min), you resolve the issue.
Disabling the "only full group by" option
Alternatively, although not advised, you can return to the old behaviour of MySql, by clearing this option:
SET sql_mode = ''
Concerning the procedure and view
As you provided the actual SQL you have in an update of your question, I add here my observation on that:
The view's select groups the result by patientid in order to aggregate the types of the associated physicians. However, you also select the physicianid: this makes little sense, as in general you might have several different physicians associated with one patient, so its value is not singular. You should just omit that field -- or if you really need one physician per patient, you should ask yourself the question: which one, if there is more than one? Here I will suggest to omit it:
select patientid AS patientid,
group_concat(physiciantypeid separator ',') AS physiciantypeid
from patientphysicians
group by patientid
Secondly, the procedure's SQL is also in need of correction. You seem to want to list the details of all the physicians associated with one particular patient. For that purpose it makes no sense to join the view, as the view only returns one record for a patient, and aggregates the physician types into a comma separated list. This is not useful for the SQL you have in the procedure, where you want a separate record for each physician. So remove the view from it, and just return the physician type for each physician.
Apart from that, you should group by the same physicianid as the one you have in the select list. Don't select the physicianid from pp in the select clause and group by the physicianid from p.
Here is the suggested update:
SELECT p.physicianid,
p.physiciantypeid,
p.firstname,
p.lastname,
p.dob,
p.mobile,
p.officephone,
p.address1,
p.address2,
p.city,
p.stateid,
p.cid,
p.zip,
p.speciality,
p.about,
p.imgid
FROM patientphysicians pp
INNER JOIN physician p
ON pp.physicianid = p.physicianid
WHERE pp.patientid = patientid /* the argument */
GROUP BY p.physicianid
Note that it really helps to understand code better when you apply proper indentation.
I was hoping someone could help me figure out what I am doing wrong with a SQL query I am trying to run from within Sequel Pro. The error message says
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.id
INNER JOIN directory_person ON directory_twitter.id = directory_person.id
WH' at line 1
And the query that I have written is
SELECT directory_twitter.id, directory_twitter.name, directory_twitter.screen_name,
directory_twitter.followers, directory_group.id, directory_group.title
FROM directory_twitter, directory_group
INNER JOIN directory_person_groups
ON directory_person_groups.person_id = directory_twitter.id,
directory_person_groups.group_id = directory_group.id
INNER JOIN directory_person
ON directory_twitter.id = directory_person.id
WHERE directory_person.appears_in_directory = "1"
I am trying to get the query to return the name of the users (directory_twitter.name), their screen name (directory_twitter.screen_name), their total number of followers (directory_twitter.followers), and the name of the group they are in (directory_group.title). Unfortunately the way our tables are set up, the only way I can think to join the group to the user is by INNER JOIN-ing a third table (directory_person_groups) where the group ID and the user ID are both present.
Finally, the only users that I want to be returned by this query are those who are in our directory (WHERE directory_person.appears_in_directory = "1"). In the table directory_person, directory_person.id = directory_twitter.id.
I have been trying to figure out what my error is for hours and I've made no progress. Is everything correct except a syntax error that I am unfamiliar with? Any and help is greatly appreciated. Thank you!
EDIT: All of the columns of the tables that I'm querying are below.
directory_twitter: id, person_id (which is the same value as id), screen_name, name, followers, user_id (I'm not sure where else this selector is used in the database, it is a different value from id and person_id).
directory_group: id (different from directory_twitter.id), slug(a slug of the title), title, screen_name (the Twitter handle of the group, e.g. CNN for #cnn)
directory_person_groups: id (I'm not sure where else if anywhere this value appears in the database, it is different from both directory_twitter.id and directory_group.id), person_id, group_id
directory_person: id (the same as directory_twitter.id which is the same as directory_twitter.person_id), title (this value is different from directory_group.title), first_name, last_name, appears_in_directory
Try this query but you need to add some indexes or it will take a very long time to run. I would suggest you make the columns in WHERE clause as indexes before I run it if I were you.
SELECT DT.name, DT.screen_name, DT.followers, DG.title
FROM directory_twitter AS DT, directory_group AS DG, directory_person_groups AS DPG
WHERE DPG.person_id=DT.person_id AND DPG.group_id=DG.id AND DT.person_id IN
( SELECT DP.id
FROM directory_person AS DP
WHERE appears_in_directory='1'
) ;
Try this
SELECT DIRECTORY_TWITTER.ID,
DIRECTORY_TWITTER.NAME,
DIRECTORY_TWITTER.SCREEN_NAME,
DIRECTORY_TWITTER.FOLLOWERS,
DIRECTORY_GROUP.ID,
DIRECTORY_GROUP.TITLE
FROM DIRECTORY_TWITTER,
DIRECTORY_PERSON_GROUPS,
DIRECTORY_PERSON,
DIRECTORY_GROUP
INNER JOIN DIRECTORY_PERSON_GROUPS
ON DIRECTORY_PERSON_GROUPS.PERSON_ID = DIRECTORY_TWITTER.ID
AND DIRECTORY_PERSON_GROUPS.GROUP_ID = DIRECTORY_GROUP.ID
INNER JOIN DIRECTORY_PERSON
ON DIRECTORY_TWITTER.ID = DIRECTORY_PERSON.ID
WHERE DIRECTORY_PERSON.APPEARS_IN_DIRECTORY = "1"
I changed the comma to AND
I need to get a title from table 2, table 2 has title and id column.
Table 1 has some data and three of these columns concatenated together makeup the id that can be found in table 1.
I used CONCAT_WS() function and gave this column an alias name and need to use the Alias for the on argument(At least this is what I understood I needed to do)
I thought this could be a simple left join, yet it is not working for me.
This is my query
SELECT
table_openers.mail,
table_openers.f_name,
table_openers.l_name,
table_openers.Quality,
CONCAT_WS('-',
table_openers.esp,
table_openers.acc,
table_openers.group) as 't1aid',
table_groups.aid,
table_groups.group_name
FROM
lance_mailstats.table_openers
LEFT JOIN
lance_mailstats.table_groups ON table_groups.aid = t1aid;
I get results for mail, f_name, l_name, Quality and t1aid, but the aid and group_name columns of the second table return null.
I feel like you can't use an alias in the ON clause.
Try doing
LEFT JOIN
lance_mailstats.table_groups ON table_groups.aid = CONCAT_WS('-',
table_openers.esp,
table_openers.acc,
table_openers.group);
"You can use the alias in GROUP BY, ORDER BY, or HAVING clauses to refer to the column" (from dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html).
And "The conditional_expr used with ON is any conditional expression of the form that can be used in a WHERE clause" (from dev.mysql.com/doc/refman/5.1/en/join.html).
So as a logical inference you're not allowed to use aliases in ON clauses.
try to use a subquery..
it goes like this.........
ex.
SELECT
tbl1.mail, tbl1.f_name, tbl1.l_name,tbl1.Quality, tbl1.t1aid,table_groups.aid,
table_groups.group_name
FROM
(SELECT
table_openers.mail,
table_openers.f_name,
table_openers.l_name,
table_openers.Quality,
CONCAT_WS('-',
table_openers.esp,
table_openers.acc,
table_openers.group) as 't1aid',
FROM
lance_mailstats.table_openers )tbl1
LEFT JOIN
lance_mailstats.table_groups ON table_groups.aid = tbl1.t1aid;