Really trying to figure out, why SQL query doesnt go through. I assume the structure is a bit wrong, but cant figure out where exactly. The references to tables are all correct.
SELECT tap_questionnaires.id,
tap_questionnaires.NAME,
tap_questionnaires.active,
tap_useranswers_ip.questionnaire_id,
Count(tap_useranswers_ip.ip)
FROM tap_questionnaires
LEFT JOIN tap_useranswers_ip
ON tap_questionnaires.id = tap_useranswers_ip.questionnaire_id
WHERE author_email = admin#admin.com
If you use count you need to use group by for the other columns in your select clause.
SELECT TAP_questionnaires.id, TAP_questionnaires.name, TAP_questionnaires.active, TAP_useranswers_ip.questionnaire_id, COUNT(TAP_useranswers_ip.ip) FROM TAP_questionnaires LEFT JOIN TAP_useranswers_ip on TAP_questionnaires.id=TAP_useranswers_ip.questionnaire_id WHERE author_email="admin#admin.com"
group by TAP_questionnaires.id, TAP_questionnaires.active
I think TAP_questionnaires.name it's not necessary because I suppose it depends on TAP_questionnaires.id. TAP_useranswers_ip.questionnaire_id is the same value as TAP_questionnaires.id
Hope that helps!
I think this version is clearer:
SELECT q.id, q.name, q.active, COUNT(a.ip)
FROM TAP_questionnaires q LEFT JOIN
TAP_useranswers_ip a
ON on q.id = a.questionnaire_id
WHERE author_email = 'admin#admin.com'
GROUP BY q.id, q.name, q.active;
Notes:
You need a GROUP BY.
You need single quotes around the string constant.
Table aliases make the query easier to write and to read.
There is no reason to include a.questionnaire_id. You already have q.id.
Related
I do not know how to join tables based on a calculation. I have to take a substring to get the part of a string I need to match up to a column from another table. I cannot figure out how to join them and really don't know where to start.
I tried everything in my power but I literally took a beginner's class and now have to fend for myself.
Select *
From five9_data.calllog join warbird.user
ON warbird.attr_employee = substring(five9_data.calllog.agent, 4,position('#' in five9_data.calllog.agent)- 4)
Group By warbird.attr_employee
Order warbird.attr_employee
Limit 100
I tried the above in the Select command but figured out it will not work and that I need to use the calculations in the join statement, but have no idea on syntax/formula. A few examples made as simple as possible would be great. I also have issue with the Group By Order by with this.
Shown above.
Often, the join condition would look like:
from t1 join
t2
on t1.empid = concat('%', t2.agent, '%')
Or, you can just use the expression:
from t1 join
t2
on t1.empid = substring(t2.agent, 4, position('#' in t2.agent) - 4)
EDIT:
As for your example code, I would write it as:
Select b.attr_employee, . . . -- aggregation functions go here
From five9_data.calllog cl join
warbird.user u
on u.attr_employee = substring(cl.agent, 4, position('#' in cl.calllog.agent) - 4)
Group By u.attr_employee
Order u.attr_employee
Limit 100;
Here are changes to notice:
Table aliases make the query easier to write and to read.
When using GROUP BY, the only unaggregated columns in the SELECT should be the GROUP BY keys. The rest should be aggregated.
Your problem is that warbird.attr_employee is not defined, because you have missed the table name. However, u is so much easier to write and to read.
from t1 join
t2
on t1.empid = substring(t2.agent, 4, position('#' in t2.agent) - 4)
I have a table with exchange rate like below
And I am using the maxofdate to pick all these values based on currency code. But the query is giving blank.
Select USDAMOUNT * dbo.EXCHANGERATEAMT
from dbo.Amount_monthly
Left Join dbo.EXCHANGERATE on dbo.Amount_monthly.Currencycode=dbo.EXCHANGERATE.fromcurrencycode
WHERE ValidToDateTime = (Select MAX(ValidToDateTime) from dbo.EXCHANGERATE)
AND dbo.EXCHANGERATE.EXCHANGERATETYPECODE = 'DAY'
Using this statement
CONVERT(DATE,ValidToDateTime) = CONVERT(DATE,GETDATE()-1)
instead of subquery is giving me expected result.
Can someone correct this.
thanks in advance.
If I understand correctly, you need two things. First, the condition for the max() needs to match the condition in the outer query. Second, if you really want a left join, then conditions on the second table need to go in the on clause.
The resulting query looks like:
Select . . .
from dbo.Amount_monthly am Left Join
dbo.EXCHANGERATE er
on am.Currencycode = er.fromcurrencycode and
er.ValidToDateTime = (Select max(er2.ValidToDateTime)
from dbo.EXCHANGERATE er2
where er2.EXCHANGERATETYPECODE = 'DAY'
) and
er.EXCHANGERATETYPECODE = 'DAY';
I would write this using window functions, but that is a separate issue.
Try removing WHERE clause for ValidToDateTime and include it in the JOIN as AND condition
SELECT USDAMOUNT * dbo.EXCHANGERATEAMT
FROM dbo.Amount_monthly
LEFT JOIN dbo.EXCHANGERATE
ON dbo.Amount_monthly.Currencycode = dbo.EXCHANGERATE.fromcurrencycode
AND ValidToDateTime = (SELECT MAX(ValidToDateTime) --remove WHERE clause
FROM dbo.EXCHANGERATE)
AND dbo.EXCHANGERATE.EXCHANGERATETYPECODE = 'DAY';
I cleaned up your query a bit: as the other folks mentioned you needed to close the parentheses around the MAX(Date) sub-query, and if you reference a LEFT JOINed table in the WHERE clause, it behaves like an INNER JOIN, so I changed to in INNER. You also had "dbo" sprinkled in as a field prefix, but that (the namespace) only prefixes a database, not a field. I added the IS NOT NULL check just to avoid SQL giving the "null values were eliminated" SQL warning. I used the aliases "am" for the first table and "er" for the 2nd, which makes it more readable:
SELECT am.USDAMOUNT * er.EXCHANGERATEAMT
FROM dbo.Amount_monthly am
JOIN dbo.EXCHANGERATE er
ON am.Currencycode = er.fromcurrencycode
WHERE er.ValidToDateTime = (SELECT MAX(ValidToDateTime) FROM dbo.EXCHANGERATE WHERE ValidToDateTime IS NOT NULL)
AND er.EXCHANGERATETYPECODE = 'DAY'
If you're paranoid like I am, you might also want to make sure the exchange rate is not zero to avoid a divide-by-zero error.
I have a query which looks like this
$db->query("SELECT A.page_id, A.page_name FROM user_likes_pages as A , user_likes as B WHERE A.page_id = B.page_id AND B.country_id = ".$user_reg." ");
The thing is, I want to select a column from user_likes. Do I have to make a join or I can do it in different way. Thank you.
You have a join in your query, but it is implicit. You should write the query as:
SELECT ulp.page_id, ulp.page_name, ul.<whatever>
FROM user_likes ul JOIN
user_likes_pages ulp
ON ul.page_id = ulp.page_id
WHERE ul.country_id = ".$user_reg."
In addition to adding the explicit join syntax, I also changed the table aliases so they are abbreviations of the table name. This makes it easier to read the query and avoid mistakes.
You select B.columnname. You don't need a join, because you have the A.page_id = B.page_id.
I know this has been asked plenty times before, but I cant find an answer that is close to mine.
I have the following query:
SELECT c.cases_ID, c.cases_status, c.cases_title, ci.custinfo_FName, ci.custinfo_LName, c.cases_timestamp, o.organisation_name
FROM db_cases c, db_custinfo ci, db_organisation o
WHERE c.userInfo_ID = ci.userinfo_ID AND c.cases_status = '2'
AND organisation_name = (
SELECT organisation_name
FROM db_sites s, db_cases c
WHERE organisation_ID = '111'
)
AND s.sites_site_ID = c.sites_site_ID)
What I am trying to do is is get the cases, where the sites_site_ID which is defined in the cases, also appears in the db_sites sites table alongside its organisation_ID which I want to filter by as defined by "organisation_ID = '111'" but I am getting the response from MySQL as stated in the question.
I hope this makes sense, and I would appreciate any help on this one.
Thanks.
As the error states your subquery returns more then one row which it cannot do in this situation. If this is not expect results you really should investigate why this occurs. But if you know this will happen and want only the first result use LIMIT 1 to limit the results to one row.
SELECT organisation_name
FROM db_sites s, db_cases c
WHERE organisation_ID = '111'
LIMIT 1
Well the problem is, obviously, that your subquery returns more than one row which is invalid when using it as a scalar subquery such as with the = operator in the WHERE clause.
Instead you could do an inner join on the subquery which would filter your results to only rows that matched the ON clause. This will get you all rows that match, even if there is more than one returned in the subquery.
UPDATE:
You're likely getting more than one row from your subquery because you're doing a cross join on the db_sites and db_cases table. You're using the old-style join syntax and then not qualifying any predicate to join the tables on in the WHERE clause. Using this old style of joining tables is not recommended for this very reason. It would be better if you explicitly stated what kind of join it was and how the tables should be joined.
Good pages on joins:
http://dev.mysql.com/doc/refman/5.0/en/join.html (for the right syntax)
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html (for the differences between the types of joins)
I was battling this for an hour, and overcomplicated it completely. Sometimes a quick break and writing it out on an online forum can solve it for you ;)
Here is the query as it should be.
SELECT c.cases_ID, c.cases_status, c.cases_title, ci.custinfo_FName, ci.custinfo_LName, c.cases_timestamp, c.sites_site_ID
FROM db_cases c, db_custinfo ci, db_sites s
WHERE c.userInfo_ID = ci.userinfo_ID AND c.cases_status = '2' AND (s.organisation_ID = '111' AND s.sites_site_ID = c.sites_site_ID)
Let me re-write what you have post:
SELECT
c.cases_ID, c.cases_status, c.cases_title, ci.custinfo_FName, ci.custinfo_LName,
c.cases_timestamp, c.sites_site_ID
FROM
db_cases c
JOIN
db_custinfo ci ON c.userInfo_ID = ci.userinfo_ID and c.cases_status = '2'
JOIN
db_sites s ON s.sites_site_ID = c.sites_site_ID and s.organization_ID = 111
I'm trying to use the following query, and if it only has one having statement it works as expected. If I add the second having statement it does not work.
SELECT candidate.first_name,
candidate.last_name,
qualification.code,
property.value AS funding_band_value,
qualification.funding_band,
property.value AS qualification_level_value,
qualification.qualification_level_id
FROM candidate_qualification, candidate, qualification, property
WHERE candidate_qualification.candidate_id=candidate.id and
candidate_qualification.qualification_id=qualification.id
HAVING funding_band_value = (select property.value from property where qualification.funding_band=property.id) and
HAVING qualification_level_value = (select property.value from property where qualification.qualification_level_id=property.id)
Could someone explain why this doesn't work and how I should do this.
HAVING acts similarly to WHERE or GROUP BY. You reference it once to start using it and combine multiple statements with AND or OR operators. An in depth look at the query parser might give you a more explicit answer.
You don't need HAVING here, just use AND so it is part of your WHERE clause.
The subqueries are not necessary, those tables are already joined.
Something like this should be closer to what you want:
SELECT c.first_name,
c.last_name,
q.code,
p.value AS funding_band_value,
q.funding_band,
p.value AS qualification_level_value,
q.qualification_level_id
FROM candidate_qualification cq
INNER JOIN candidate c ON cq.candidate_id=c.id
INNER JOIN qualification q ON cq.qualification_id=q.id
INNER JOIN property p ON q.funding_band=p.id
and q.qualification_level_id=p.id