I am doing a query for a class where I need to select pet owner names based on whether or not they own a Chihuahua.
I have to use two tables, PetOwner and Pet. PetOwner has an owner number (ownerNo), owner name (oLName, oFName), and Pet has owner number and petType. Here is the code I am trying to use:
SELECT
PetOwner.oFName,
PetOwner.oLName
FROM
PetOwner,
Pet
WHERE
PetOwner.ownerNo = (SELECT
Pet.ownerNumber
FROM
Pet
WHERE
Pet.petType = 'Chihuahua'
);
The error says "unknown command beginning "Pet.petTyp..." - rest of line ignored." I know the issue is in the WHERE clause, but I can't seem to tweak it to where it will work, and I am sure the answer is obvious.
I just need a second set of eyes to look it over.
How can i do this ?
Inside your query:
SELECT PetOwner.oFName, PetOwner.oLName
FROM PetOwner, Pet
You have mentioned the table 'Pet' here. Table 'Pet' shouldn't be mentioned here, as you're selecting the oFName and oLName from the table 'PetOwner', not 'Pet'.
A simple join query will give you exactly what you want. No need to use subquery in the above mentioned way. You need to join Pet table with PetOwner table, based on PetOwner.ownerNo = Pet.ownerNumber, under the condition that Pet.petType is 'Chihuahua'.
So the completed query is:
SELECT po.oFname, po.oLName
FROM PetOwner as po
JOIN Pet as p
ON po.ownerNo = p.ownerNumber
WHERE p.petType = 'Chihuahua'
The following query worked for me:
SELECT ownername
FROM PetOwner
WHERE PetOwner.ownerNo = (SELECT Pet.ownerNo FROM Pet WHERE Pet.petType = 'Chihuahua');
Regards.
SELECT oFName, oLName
FROM PetOwner
WHERE ownerNo = (SELECT ownerNumber FROM Pet WHERE petType = 'Chihuahua');
Your query is confusing sql for which Pet to select parent one or child one. Provide alias for child table in your sub query as mentioned below :
SELECT
PetOwner.oFName,
PetOwner.oLName
FROM
PetOwner,
Pet
WHERE
PetOwner.ownerNo = (SELECT
p.ownerNumber
FROM
Pet p
WHERE
p.petType = 'Chihuahua'
);
Related
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 need help with a complex select statement in SQL. I have these two table here:
Table user:
Table contacts_from_user:
When I make a select
SELECT name, vorname, gebdat, bezeichnung, wert
FROM user
JOIN contacts ON u_id = user_u_id
I get multiple lines for one user because he has more then one contact options but I need to put it in just one line:
The line should be looks like this:
name, vorname, gebdat, bezeichung_1, wert_1, bezeichnung_2, wert_2.......
How ca I do this?
Thanks a lot!
In pseudo-code, the best way to handle such scenarios is:
query = SELECT A.ID, A.stuff, B.stuff FROM A JOIN B ON A.ID = B.A_ID
results = run query
prev_A_ID = impossible_A_ID
for each result
if prev_A_ID not equal result_A_ID
create new A and set as current A
add B.stuff to current A
set prev_A_ID to result_A_ID
end for
dont blame for the database design.I am not its database architect. I am the one who has to use it in current situation
I hope this will be understandable.
I have 3 tables containing following data with no foreign key relationship b/w them:
groups
groupId groupName
1 Admin
2 Editor
3 Subscriber
preveleges
groupId roles
1 1,2
2 2,3
3 1
roles
roleId roleTitle
1 add
2 edit
Query:
SELECT roles
from groups
LEFT JOIN preveleges ON (groups.groupId=preveleges.groupId)
returns specific result i.e roles.
Problem: I wanted to show roleTitle instead of roles in the above query.
I am confused how to relate table roles with this query and returns required result
I know it is feasible with coding but i want in SQL.Any suggestion will be appreciated.
SELECT g.groupName,
GROUP_CONCAT(r.roleTitle
ORDER BY FIND_IN_SET(r.roleId, p.roles))
AS RoleTitles
FROM groups AS g
LEFT JOIN preveleges AS p
ON g.groupId = p.groupId
LEFT JOIN roles AS r
ON FIND_IN_SET(r.roleId, p.roles)
GROUP BY g.groupName ;
Tested at: SQL-FIDDLE
I would change the data structure it self. Since It's not normalised, there are multiple elements in a single column.
But it is possible with SQL, if for some (valid) reason you can't change the DB.
A simple "static" solution:
SELECT REPLACE(REPLACE(roles, '1', 'add'), '2', 'edit') from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
A more complex but still ugly solution:
CREATE FUNCTION ReplaceRoleIDWithName (#StringIds VARCHAR(50))
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #RoleNames VARCHAR(50)
SET #RoleNames = #StringIds
SELECT #RoleNames = REPLACE(#RoleNames, CAST(RoleId AS VARCHAR(50)), roleTitle)
FROM roles
RETURN #RoleNames
END
And then use the function in the query
SELECT ReplaceRoleIDWithName(roles) from groups
LEFT JOIN preveleges ON(groups.groupId=preveleges.groupId)
It is possible without function, but this is more readable. Made without editor so it's not tested in anyway.
You also tagged the question with PostgreSQL and it's actually quite easy with Postgres to work around this broken design:
SELECT grp.groupname, r.roletitle
FROM groups grp
join (
select groupid, cast(regexp_split_to_table(roles, ',') as integer) as role_id
from privileges
) as privs on privs.groupid = grp.groupid
join roles r on r.roleid = privs.role_id;
SQLFiddle: http://sqlfiddle.com/#!12/5e87b/1
(Note that I changed the incorrectly spelled name preveleges to the correct spelling privileges)
But you should really, really re-design your data model!
Fixing your design also enables you to define foreign key constraints and validate the input. In your current model, the application would probably break (just as my query would), if someone inserted the value 'one,two,three' into the roles table.
Edit
To complete the picture, using Postgres's array handling the above could be slightly simplified using a similar approach as MySQL's find_in_set()
select grp.groupname, r.roletitle
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
In both cases if all role titles should be shown as a comma separated list, the string_agg() function could be used (which is equivalent to MySQL's group_concat()
select grp.groupname, string_agg(r.roletitle, ',')
from groups grp
join privileges privs on grp.groupid = privs.groupid
join roles r on r.roleid::text = any (string_to_array(privs.roles, ','))
group by grp.groupname
I got the following sql question that I that won´t work for me. I know that the last CASE row are wrong but I would like to use a CASE statement like that in my where clause.
Short description of my situation:
I got several companies that got there own material linked to them with "companyID". Each material might be linked to a row in pricelist_entries. If I search for one row in the pricelist_entries table that is linked to many material rows all rows will be returned but I just want to return the one that belongs to the current company (the company that performs the search).
Conclusion: If materialID NOT NULL THEN materials.company="current.companyID".
SELECT peID, peName, materialID
FROM pricelist_entries
INNER JOIN pricelist ON pricelist_entries.peParentID=pricelist.pID
LEFT JOIN materials ON pricelist_entries.peID=materials.pricelist_entries_id
WHERE peBrand = 'Kama' AND pricelist.pCurrent = 1
AND (peName LIKE '%gocamp de%' OR peArtnr LIKE '%gocamp de%')
AND pricelist.country=0 AND pricelist_entries.peDeleted=0
CASE materialID WHEN IS NOT NULL THEN materials.companyID=10 END
Please tell me if I need to describe my problem in a better way.
Thanks in advance!
Sounds like just moving the condition into the join would make it simpler;
SELECT peID, peName, materialID
FROM pricelist_entries
INNER JOIN pricelist
ON pricelist_entries.peParentID=pricelist.pID
LEFT JOIN materials
ON pricelist_entries.peID=materials.pricelist_entries_id
AND materials.companyID=10 -- << condition
WHERE peBrand = 'Kama' AND pricelist.pCurrent = 1
AND (peName LIKE '%gocamp de%' OR peArtnr LIKE '%gocamp de%')
AND pricelist.country=0 AND pricelist_entries.peDeleted=0
It will only left join in material rows that are linked to the correct company.
You can't use CASE in the where clause that I'm aware of, you need to use it in the SELECT portion, but it will have the same effect. Something like this should work:
SELECT CASE materialid WHEN IS NOT NULL THEN companyid END as thiscompanyid
This will give you a new column named thiscompanyid and you can query off of that to get what you need.
Here i posted a question about doing JOIN depending on the value of the column in the row.
You will need that is you make an Add Friend feature, where you write the ID of the 2 users who are Adding each other into user_1_id (my id) and user_2_id (friend id).
When you want to see who you are friends with, select DEPENDING on whether user_1_id or user_2_id has the ID of the surrent User (the one who is browsing)
I figured it out so down below is the query you want to use in case you need to do it.
Here is the query
$sql_inp = 'SELECT DISTINCT
users.id, users.first_name, users.last_name,
CASE
WHEN friends.user_2_id="'.$_SESSION[USER][id].'" //equal to current user id
THEN (SELECT friends.user_1_id FROM friends WHERE friends.user_2_id="'.$_SESSION[USER][id].'") // if user_2_id is My id, then fetch the other row
ELSE friends.user_2_id // obviously the opposite
END
FROM users
LEFT JOIN friends ON users.id= // this case is completely the same as one above
CASE
WHEN friends.user_2_id="'.$_SESSION[USER][id].'" THEN (SELECT friends.user_1_id FROM friends WHERE friends.user_2_id="'.$_SESSION[USER][id].'")
ELSE friends.user_2_id
END
WHERE friends.user_1_id="'.$_SESSION[USER][id].'" OR friends.user_2_id="'.$_SESSION[USER][id].'" // fetch the row where the either one of the values is equal to My id
';
Hope this helps if anyone had trouble
Personally, I hate using CASE statement. It makes queries look cluttered. Try using the IF function
$sql_inp = 'SELECT
table1.val1,table1.val2,
table2.val1,table2.val2,
IF(table3.val1="'.$user_id.'",table3.val1,
IF(table3.val2 ="'.$user_id.'",table3.val2,
IFNULL(table3.val2,-1))) users_fetch
FROM table1
INNER JOIN table2 ON table2.val1=table1.val1
LEFT JOIN table3 ON table2.val1=users_fetch';
In this query, if table3.val1 and table3.val2 <> $user_id, then users_fetch is -1.
Give it a Try !!!