How to use VIEW in WHERE clause (MySQL)? - mysql

I want to use data of view in WHERE clause. But getting an error:
create view post_with_answers AS
SELECT DISTINCT postid
FROM (SELECT postid FROM `qa_posts` WHERE `type` = 'Q') AS q1
INNER JOIN (SELECT parentid FROM `qa_posts` WHERE `type` = 'A') AS q2 ON q1.postid = q2.parentid
select count(*)
from qa_posts
where parentid not in post_with_answers
On the last row I am getting this error:
SQL Error [1064] [42000]: 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 'post_with_answers' at line 3
How to fix that?

Just like you would use a table:
select count(*)
from qa_posts
where parentid not in (select pwa.postid from post_with_answers pwa);
I would caution you from using not in with a subquery. No rows are returned if even one value from the subquery is NULL. For this reason, I recommend NOT EXISTS:
select count(*)
from qa_posts p
where not exists (select 1
from post_with_answers pwa
where p.parentid = pwa.postid
);
In addition, your view definition is a bit over complicated. You don't need subqueries:
create view post_with_answers AS
SELECT DISTINCT pq.postid
FROM qa_posts pq JOIN
qa_posts pa
ON pq.postid = pa.parentid
WHERE pq.type = 'Q' AND pa.type = 'A';
Then, the DISTINCT just adds overhead, so EXISTS is better:
create view post_with_answers AS
SELECT DISTINCT pq.postid
FROM qa_posts pq
WHERE EXISTS (SELECT 1
FROM qa_posts pa
WHERE pq.postid = pa.parentid AND
pa.type = 'A'
)
WHERE pq.type = 'Q';

Related

Error in mysql query with IF statement and sub query

I have (for me at least) a complex query that I build with examples from this site. The last thing I added was the IF statement. Without the IF statement it was working with the TRUE part of the IF statement. I hope you girls/guys can help me out here. This is the query :
SELECT
t.ID, t.start_time, t.end_time, t.start_date, t.end_date, t.balance,
u1.first_name AS teacher_one_first_name, u1.last_name AS teacher_one_last_name,
u2.first_name AS teacher_two_first_name, u2.last_name AS teacher_two_last_name,
company.name, company.post_city, tag, lvl,
IF(
t.balance=1,
(
(SELECT count(user_ID)
FROM company_lesson_block_student
WHERE lead_follow=0 AND company_lesson_block_ID=t.ID) AS lead,
(SELECT count(user_ID)
FROM company_lesson_block_student
WHERE lead_follow=1 AND company_lesson_block_ID=t.ID) AS follow
),
(SELECT count(user_ID)
FROM company_lesson_block_student
WHERE company_lesson_block_ID=t.ID) AS total_student
)
FROM company_lesson_block AS t
LEFT JOIN company_lvl ON company_lvl.ID = t.lvl_ID
LEFT JOIN tag ON tag.ID = t.style_ID
LEFT JOIN company ON company.ID=t.location_ID
LEFT JOIN user AS u1 ON t.teacher_one_ID=u1.ID
LEFT JOIN user AS u2 ON t.teacher_two_ID=u2.ID
WHERE t.company_ID='1' AND location_ID='1' AND company_season_ID='1'
ORDER BY start_date ASC
The error message i get is:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version
for the right syntax to use near 'AS lead, (SELECT count(user_ID) FROM company_less' at line 10
Any help/tips are appriciated
You want to return 2 columns, but IF can return only 1, so you need 2 IFs:
........................
IF(
t.balance=1,
(SELECT count(user_ID)
FROM company_lesson_block_student
WHERE lead_follow=0 AND company_lesson_block_ID=t.ID),
(SELECT count(user_ID)
FROM company_lesson_block_student
WHERE company_lesson_block_ID=t.ID)
) AS ????,
IF(
t.balance=1,
(SELECT count(user_ID)
FROM company_lesson_block_student
WHERE lead_follow=1 AND company_lesson_block_ID=t.ID),
(SELECT count(user_ID)
FROM company_lesson_block_student
WHERE company_lesson_block_ID=t.ID)
) AS ????
........................
You must set the aliases after the closing parenthesis of IF.
Maybe you must rethink this logic because in case of FALSE, the same value is returned twice.

Using if condition to display in mysql

I'm trying to display manager_id using the user_id and role_id as inputs in MySQL. This is what I've tried:
SELECT cbm_user.user_id as user_id
IF (cbm_roles.role_id = 3 THEN SELECT cbm_user.manager_id as manager_id, cbm_user.user_id as user_id, cbm_user_role.role_id as role_id from cbm_user left outer join cbm_user_role on cbm_user.user_id = cbm_user_role.user_id, left outer join cbm_roles on cbm_user_role.role_id = cbm_roles.role_id where role_id = 3)
END if;
But I get
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'IF (cbm_roles.role_id = 3 THEN SELECT cbm_user.manager_id as manager_id, cbm_use' at line 2
error. What should I do? I also want to add two more conditions. How can I do that?
You are using IF in wrong way.
You are using join in wrong way means "," join as well left join together.
You can use your query below 2 types-
USE OF IF
SELECT cbm_user.user_id AS user_id
IF (cbm_roles.role_id = 3,cbm_user.manager_id,NULL) AS manager_id,
cbm_user.user_id AS user_id, cbm_user_role.role_id AS role_id
FROM cbm_user
LEFT JOIN cbm_user_role ON cbm_user.user_id = cbm_user_role.user_id
LEFT JOIN cbm_roles ON cbm_user_role.role_id = cbm_roles.role_id
WHERE role_id = 3;
use of case
SELECT cbm_user.user_id AS user_id
CASE WHEN cbm_roles.role_id = 3 THEN cbm_user.manager_id END AS manager_id,
cbm_user.user_id AS user_id, cbm_user_role.role_id AS role_id
FROM cbm_user
LEFT JOIN cbm_user_role ON cbm_user.user_id = cbm_user_role.user_id
LEFT JOIN cbm_roles ON cbm_user_role.role_id = cbm_roles.role_id
WHERE role_id = 3;
There are several syntax errors in your statement:
missing comma between fields
incorrect use of if() function
extra comma in join expression
To sum up: you cannot use an if() function to decide what tables to join. I fixed the syntax errors below, but I do not think that this is the query you want.
SELECT cbm_user.user_id as user_id,
IF(cbm_roles.role_id = 3, cbm_user.manager_id, null) as manager_id,
cbm_user_role.role_id as role_id
from cbm_user
left outer join cbm_user_role on cbm_user.user_id = cbm_user_role.user_id
left outer join cbm_roles on cbm_user_role.role_id = cbm_roles.role_id
where cbm_user_role.role_id = 3

Join 3 table is giving an error

i have 3 tables.
tenant
tenant_id : int
category_id : int
category
category_id : int
category_name : varchar(50)
history
tenant_id : int
bulan_tahun : varchar(8)
counter : int
i want to join all of this table using this code:
SELECT a.tenant_id, a.category_name
FROM (
(tenant INNER JOIN category ON tenant.category_id = category.category_id) AS a
INNER JOIN (
SELECT tenant_id, counter FROM history WHERE
bulan_tahun = DATE_FORMAT(CURDATE(), '%m_%Y')
) AS b
on a.tenant_id = b.tenant_id
)
but this code produce an error:
#1064 - 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 'a INNER JOIN ( SELECT tenant_id, counter FROM history WHERE bulan_tahun ' at line 3
if i separate the sub select, it works perfectly
for the first select:
SELECT tenant_id, category_name
FROM
(tenant INNER JOIN category ON tenant.category_id = category.category_id)
and the second select:
SELECT tenant_id, counter FROM history WHERE
bulan_tahun = DATE_FORMAT(CURDATE(), '%m_%Y')
but if i join this together, the error occured
can anyone help me?
Problem lies here..
(tenant INNER JOIN category ON tenant.category_id = category.category_id)
Try restructuring your entire query like this
SELECT a.tenant_id, c.category_name
FROM
tenant t
INNER JOIN
category c
ON ( t.category_id = c.category_id )
INNER JOIN
history h
ON ( t.tenant_id = h.tenant_id )
WHERE
h.bulan_tahun = DATE_FORMAT(CURDATE(), '%m_%Y')

Counting rows from different tables in same query

I thought i did something like this before:
$reg = mysql_query ("(SELECT count(*) from vouchers) as total_vouchers),
(SELECT count(*) from vouchers WHERE asignado = 1) as vouchers_asignados,
(SELECT count(*) from crm) as crm_users,
(SELECT count(*) from datos_modificados) as dm_users") or die(mysql_error());
But it would return mysql_error near the first , :
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 'as total_vouchers), ((SELECT count(*) from vouchers WHERE asignado = 1) a' at line 1
Any idea why?
Try to add select as below
$reg = mysql_query ("SELECT
(SELECT count(*) from vouchers) as total_vouchers,
(SELECT count(*) from vouchers WHERE asignado = 1) as vouchers_asignados,
(SELECT count(*) from crm) as crm_users,
(SELECT count(*) from datos_modificados) as dm_users") or die(mysql_error());

Adding sub query - SQL Server 2008

I have following SQL query but this is not quite what I want:
SELECT
TOP (20) Attribs.ImageID AS ItemID
FROM
Attribs
LEFT OUTER JOIN
Items ON Attribs.ImageID = Items.ImageID
WHERE
(attribID IN ('a','b','c','d','e'))
AND (deleted NOT IN (1,2))
AND Attribs.attribID = 'a' AND Attribs.attribID = 'b'
GROUP BY
Attribs.ImageID
ORDER BY
COUNT(DISTINCT attribID) DESC
What I need is to query
AND Attribs.attribID = 'a' AND Attribs.attribID = 'b'
first, then rest of the WHERE clause based on the above query results.
Is this possible to achieve using sub query?
I'm using SQL Server 2008
Thank you
I'm not totally getting the reason why you want to do this one query first before the other.... but you could use a Common Table Expression (CTE) - something like this:
;WITH FirstQuery AS
(
SELECT a.ImageId
FROM dbo.Attribs a
WHERE a.attribID = 'a' AND a.attribID = 'b'
)
SELECT
TOP (20) a.ImageID AS ItemID
FROM
dbo.Attribs a
INNER JOIN
FirstQuery fq ON a.ImageId = fq.ImageId
LEFT OUTER JOIN
dbo.Items i ON a.ImageID = i.ImageID
WHERE
(attribID IN ('a','b','c','d','e'))
AND (deleted NOT IN (1,2))
GROUP BY
a.ImageID
ORDER BY
COUNT(DISTINCT attribID) DESC
With this, you first select the ImageID from your dbo.Attribs table in the CTE, and then join that result set with the result of the table and join to the Items table.
You want to do that for performance issues? Because splitting this up won't change the results.
Anyway, you can do this like:
SELECT TOP (20) rn_Attribs.ImageID AS ItemID
FROM (SELECT *
FROM Attribs
WHERE Attribs.attribID = '123' AND Attribs.attribID = '456') rn_Attribs
LEFT OUTER JOIN Items ON rn_Attribs.ImageID = Items.ImageID
WHERE(attribID IN ('a','b','c'))
AND (deleted NOT IN (1,2))
GROUP BY rn_Attribs.ImageID
ORDER BY COUNT(DISTINCT attribID) DESC