SQL Multiple subquery issue - sql

Currently struggling with a second subquery (t3) which is giving me a syntax error. The query works fine if t3 is excluded.
SELECT switch(LEFT(t1.[treatment],1)='C',"Complaint",LEFT(t1.[treatment],1)='P',"Post") AS Treatment, count(t1.[ID]) AS Total_Vol, count(t2.[event]) AS Total_Posted, format(count(t2.[event]) / count(t1.[ID]),"0.00%") AS Percentage, COUNT(IIF(t1.[requirements]='1',1,)) AS Special _Population,count(t3.[approved]) as Approved_vol
FROM Main_audit_table_v3 AS t1 LEFT JOIN (SELECT t2.[ID], t2.[event] FROM Main _table AS t2 WHERE t2.event Not Like ('NA')) AS t2 ON t1.[ID] = t2.[ID]
LEFT JOIN (SELECT t3.[ref],t3.[requirement],t3.[approved] from Main_table AS t3 where
t3.[requirement] = '1' and t3.[approved] not like ('NA')) as t3
t2.[ID] = t3.[ID]
GROUP BY LEFT(t1.[treatment],1);
The expected output is that the [approved] column will provide a count of records where requirement = 1 and approved not like NA.

In MS Access you need additional parentheses for JOINs. And you are missing ON:
SELECT . . .
FROM (Main_audit_table_v3 AS t1 LEFT JOIN
(SELECT t2.[ID], t2.[event]
FROM Main _table AS t2
WHERE t2.event Not Like ('NA')
) AS t2 ON t1.[ID] = t2.[ID]
) LEFT JOIN
(SELECT t3.[ref], t3.[requirement], t3.[approved]
FROM Main_table AS t3
WHERE t3.[requirement] = '1' and t3.[approved] not like 'NA'
) as t3
ON t2.[ID] = t3.[ID]
GROUP BY LEFT(t1.[treatment], 1);

Related

SQL query to fetch data based on column value

Is it possible to get entire data in one attempt for this scenario? I have this query where I need retrieve product name from another table.
SELECT T1.CASE_ID,
T2.PRODUCT_ID,
T2.LEVEL,
(CASE WHEN T2.LEVEL = 3 THEN T3.PARENT_PRODUCT_ID
WHEN T2.LEVEL = 2 THEN T2.PRODUCT_ID
WHEN T2.LEVEL = 1 THEN NULL END) AS NEW_PRODUCT_ID,
T3.PRODUCT_NAME
FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2
ON T1.CASE_ID = T2.CASE_ID
LEFT OUTER JOIN TABLE3 T3
ON T2.PRODUCT_ID=T3.PRODUCT_ID
Right now the T3.PRODUCT_NAME return value based on T2.PRODUCT_ID but what I really need is to able to retrieve data based on the value from NEW_PRODUCT_ID?
Here is my expected output:
Hope this makes sense.
You can use a subquery
SELECT T4.CASE_ID, T4.PRODUCT_ID, T4.LEVEL, T4.NEW_PRODUCT_ID, T5.PRODUCT_NAME
FROM (
SELECT T1.CASE_ID,
T2.PRODUCT_ID,
T2.LEVEL,
(CASE WHEN T2.LEVEL = 3 THEN T3.PARENT_PRODUCT_ID
WHEN T2.LEVEL = 2 THEN T2.PRODUCT_ID
WHEN T2.LEVEL = 1 THEN NULL END) AS NEW_PRODUCT_ID,
T3.PRODUCT_NAME
FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2
ON T1.CASE_ID = T2.CASE_ID
LEFT OUTER JOIN TABLE3 T3
ON T2.PRODUCT_ID=T3.PRODUCT_ID
) AS T4
LEFT OUTER JOIN TABLE3 T5
ON T4.NEW_PRODUCT_ID=T5.PRODUCT_ID

How to add a field from another table to a left join query MS Access

I have a query that involves both left join and not exists statements. Thus this query is not supported in design view. I would like to add a field "comments" from another table "Table2". Is this possible with the query I have created? The code is as follows:
SELECT t.NUM, t.ID, tprev.Date_ AS previous_date, tprev.Measurement AS previous_measurement
FROM Table1 AS t LEFT JOIN
Table1 AS tprev
ON (tprev.id = t.id) AND (tprev.Date_ < t.Date_)
WHERE not exists
(select 1
from Table1 AS t1
where
t1.ID = t.ID
and t1.Date_ < t.Date_
and t1.Date_ > tprev.Date_);
Following your example of your last comment, this query works without any complains regarding syntax:
SELECT t.NUM, t.ID, tprev.Date_ AS previous_date, tprev.Measurement AS previous_measurement
FROM (
(
Table2 AS t2
INNER JOIN Table1 AS t
ON (t2.Comments = t.ID)
)
LEFT JOIN Table1 AS tprev
ON tprev.Date_ < t.Date_ AND tprev.id = t.id
)
WHERE not exists (select 1 from Table1 AS t1 where t1.ID = t.ID and t1.Date_ < t.Date_ and t1.Date_ > tprev.Date_);
The reason for the syntax error was that this parenthesis t.Date_) was too much.
If it is logically fine, you should know.
What smells a bit are those:
You compare Comments with ID. Maybe it should be CommentID?
The fieldname Date_. Maybe you can find a better name without having to use an underscore?
Update
Following the comments of this answer and the new requirements, this should be what you need:
SELECT
t.NUM, t.ID, tprev.Date_ AS previous_date, tprev.Measurement AS previous_measurement, t2.Comments
FROM
(
Table1 AS t
LEFT JOIN Table2 AS t2
ON t.ID = t2.ID
)
LEFT JOIN Table1 AS tprev
ON (tprev.id = t.id) AND (tprev.Date_ < t.Date_)
WHERE
NOT EXISTS (SELECT 1 FROM Table1 AS t1 WHERE t1.ID = t.ID AND t1.Date_ < t.Date_ AND t1.Date_ > tprev.Date_)
It finally is the query of your question enhanced by another left join to add the column Comments from table2 where a corresponding comment exists.

Convert to join query

select t.* from table1 t where t.id NOT IN(
select Id from t2 where usrId in
(select usrId from t3 where sId=value));
I the result i need is like if there are matching id's in t1 and t2 then those id's should be omitted and only the remaining rows should be given to me. I tried converting into join but it is giving me the result i wanted. Below is my join query.
SELECT t.* FROM table1 t JOIN table2 t2 ON t.Id <> t2.Id
JOIN table3 t3 ON t3.Id=t2.Id WHERE t3.sId= :value
This doesn't feth me the correct result. it was returning all the rows, but i want to restrict the result based on the matching id's in table t1 and table t2. Matching id's should be ommited from the result.I will be passing the value for sId.
I believe this to be an accurate refactor of your query using joins. I don't know if we can do away with the subquery, but in any case the logic appears to be the same.
select t1.*
from table1 t1
left join
(
select t2.Id
from table2 t2
inner join table3 t3
on t2.usrId = t3.usrId
where t3.sId = <value>
) t2
on t1.Id = t2.Id
where t2.Id is null
Let's break down and solve problem step by step.
So your query
select t.* from table1 t where t.id NOT IN(
select Id from t2 where usrId in
(select usrId from t3 where sId=value));
on converting the inner query to JOIN will yield
select t.* from table1 t where t.id NOT IN
(SELECT T2.ID FROM T2 JOIN T3 on T2.UsrID =T3.UsrID and T3.sID=value)
which on further converting to JOIN with outer table will be
select t.* from table1 t LEFT JOIN
(SELECT T2.ID FROM T2 JOIN T3 on T2.UsrID =T3.UsrID and T3.sID=value)t4
ON t.id =T4.ID
WHERE t4.ID is NULL
In case you completely want to remove sub-query you can try like this
SELECT t.*
FROM table1 t
LEFT JOIN T2
ON T.ID=T2.ID
LEFT JOIN T3
ON T3.UsrId=T2.UsrID AND T3.sId=value
WHERE T3.UsrID IS NULL

SQL query - filter with cascading conditions

I've two tables T1 and T2 with the following columns -
T1
Project_ID
Category
Column_X
Column_Y
Column_Z
T2
Proj_ID
Category
Parent_Project_ID
I want to write a query to get records from T1 with the following condition -
Get Projects with Category = "A" from T1
Get child projects of the above filtered projects
I'm not sure how to check the second condition only with the results coming out of first condition.
What is needed?
Projects from T1 where Category is A
Child projects of projects obtained from condition 1
Adding sample data and desired results as requested -
To get all records from second table then you can use the following query.
SELECT
t2.*
FROM T1 t1
RIGHT OUTER JOIN T2 t2 ON t1.Project_ID = t2.Project_ID
WHERE t1.Category = "A"
SELECT * FROM T2 WHERE T2.Proj_ID IN ( SELECT Project_ID FROM T1 WHERE Category = 'A' )
This should do the job needed.
SELECT * from T2 as d
WHERE EXISTS ( SELECT * from T1 as d1 where d1.Category = 'A' and d1.Project_ID = d.Proj_ID )
SELECT * from T1 as d1 right join T2 as d2 on d1.Project_ID = d2.Proj_ID
WHERE d1.CodTert = 500
I've made an update, these query give the same result, one uses the JOIN one doesn't.
I'm assuming that T2.Parent_Project_ID and T1.Project_ID are related. If so, you can use this:
Select T3.*
From T1
Join T2 On T2.Parent_Project_ID = T1.Project_ID
Join T1 T3 On T3.Project_ID = T2.Proj_ID
Where T1.Category = 'A'
This would get only child projects of projects that have a category of 'A'.
EDIT:
Based on the output format that has been added to the question, the following query, which uses a LEFT OUTER JOIN would render the exact result required:
SELECT
T2.PROJ_ID Project_ID,
T2.Category,
T1.Column_X,
T1.Column_Y,
T1.Column_Z,
T2.Parent_Project_ID
FROM T1 T1_PARENTS
INNER JOIN T2
ON T2.Parent_Project_ID = T1.Project_ID and T1.Category = 'A'
INNER JOIN T2 T2_CHILDREN
ON T2_CHILDREN.PROJ_ID = T2.Parent_Project_ID OR T2_CHILDREN.Parent_Project_ID = T2.Parent_Project_ID
LEFT OUTER JOIN T1
ON T2_CHILDREN.PROJ_ID = T1.Project_ID;

Transform select count(*) inside a inner join

My problem here is that i'm modifying an existing query and i cannot use count(*) in the query.
I have to use inner join subqueries.
What i need to "transform" into my inner join is like this (this works):
SELECT count(distinct t1.id)
FROM table1 t1
WHERE t1.column1 = 'value1' AND
t2.column2 = 'value2' AND
EXISTS(select 1 from table2 t2 where t2.id = t1.id)
My global query looks like this:
SELECT [many many column]
FROM table2 t2
INNER JOIN [...]
LEFT OUTER JOIN [...]
--[I NEED MY COUNT HERE, see below for example]
WHERE [some conditions are true]
ORDER BY [some column]
What i found to help me is something like this:
SELECT [many many column], myJoin.Count
FROM table2 t2
INNER JOIN (
SELECT tt2.id, count(distinct tt2.id) as Count
FROM table2 tt2
WHERE EXISTS (SELECT 1 FROM table1 tt1 where tt1.id = tt2.id)
GROUP BY tt2.id) myJoin
on t2.id = myJoin.id;
See what i'm trying to acheive? I need to count the ids, joining 2 tables, but i can't have a count in my main query, i can't possibly copy-paste all the "group by" condition that would go with it...
I'm on sql server.
If i find the answer i will come back and post it.
Thanks for any advice/tricks about this.
How about the following:
SELECT table2.*, TopQ.MyCount
FROM (
SELECT t2.id, myJoin.MyCount
FROM table2 t2
INNER JOIN (
SELECT tt2.id, count(distinct tt2.id) as MyCount
FROM table2 tt2
WHERE EXISTS
(SELECT 1 FROM table1 tt1 where tt1.id = tt2.id)
GROUP BY tt2.id) AS myJoin
on t2.id = myJoin.id
)AS TopQ
INNER JOIN table2 ON TopQ.id = table2.id
I came across this:
select count(distinct t1.id) over (partition by t1.aColumn) as myCount,
[many many column]
from table2 t2
inner join table1 t1 on [someConditions] = value1 and
[someConditions] = value2 and
t2.id = t1.id;
I get the same results as my first select i posted in my question, and without adding a "group by" anywhere and a lot of inner join that im not that familliar with. I'm gonna stick with this solution.
Thanks!