missing FROM-clause entry for table when using string_agg - sql

I have this query to try to search for the course that fulfills 3 requirements.
select
course.id,
course.title,
course.number,
string_agg(requirement.description,'; ' order by requirement.description)
from course
join
(
select course.id, course.title, course.number
from requirement join course_requirement
on (requirement.id=course_requirement.requirement)
join course on (course.id=course_requirement.course)
where requirement.description='Human Behavior'
) as c1
on (c1.id=course.id)
join
(
select course.id, course.title, course.number
from requirement
join course_requirement
on (requirement.id=course_requirement.requirement)
join course
on (course.id=course_requirement.course)
where requirement.description='Intercultural'
) as c2
on (c1.id=c2.id)
join
(
select course.id, course.title, course.number
from requirement
join course_requirement
on (requirement.id=course_requirement.requirement)
join course
on (course.id=course_requirement.course)
where requirement.description='Religion'
) as c3
on (c1.id=c3.id)
group by course.id, course.title, course.number;
However, I receive this message: ERROR: missing FROM-clause entry for table "requirement"
LINE 1: ...course.id, course.title, course.number,string_agg(requiremen...
Can you tell me where did I get the query wrong?
Thank you so much!

I don't see the point of the three joined subqueries, which differ only in the requirement description in the WHERE clause. Instead, you might try a single query which uses WHERE IN to capture the three descriptions you want in your result set. This also fixes the problem you had with string_agg(), where you were trying to aggregate something from a subquery not reachable in the outer query.
Try the following query:
select
t1.id,
t1.title,
t1.number,
string_agg(t3.description, '; ' order by t3.description)
from course t1
inner join course_requirement t2
on t1.id = t2.course
inner join requirement t3
on t2.requirement = t3.id
where t3.description in ('Human Behavior', 'Intercultural', 'Religion')
group by t1.id, t1.title, t1.number;

Related

Sum Column in Joined Table and add as column SQL

So say I have two tables in Oracle SQL (not actually data but for ease should highlight my question)
Table1 that contains only Order_id and Order_quantity and Table2 that contains only Order_id and Order_price
Then I join them as follows
Select T1.Order_id,
T1.Order_quantity,
T2.Order_price,
T1.Order_quantity*T2.Order_price As "Order_amount",
Sum(Order_amount) As "Total_Sales"
from Table1 T1
inner join Table2 T2
on T1.Order_id = T2.Order_id
So essentially I want to have two extra columns, one as the product of columns from the two tables, and another as the sum of that column in my joined table(so every entry will be the same). However as you need to
SUM(variable_name) From Table_Name
Can I assign a variable name to my new table and then refer to that. I tried the following but I'm getting a SQL command not properly ended error
Select T1.Order_id,
T1.Order_quantity,
T2.Order_price,
T1.Order_quantity*T2.Order_price As "Order_amount",
Sum(Order_amount) from New_Table As "Total_Sales"
from (Table1 T1
inner join Table2 T2
on T1.Order_id = T2.Order_id) As New_Table
Thanks for any assistance, apologies as I have a pretty naive understanding of SQL at present
I think you just want a window function:
select T1.Order_id, T1.Order_quantity, T2.Order_price,
T1.Order_quantity*T2.Order_price As order_amount,
sum(T1.Order_quantity*T2.Order_price) over () As Total_Sales
from Table1 T1 inner join
Table2 T2
on T1.Order_id = T2.Order_id
You cannot re-use the alias order_amount in the select. You need to repeat the expression -- or use a subquery or CTE to define it.
If your DBMS doesn't have a window function supports then you can use subquery instead
select order_id, Order_quantity,
(select t1.Order_quantity * t2.Order_price
from table2 t2
where t2.Order_id = t1.Order_id) as Order_amount,
(select sum(t1.Order_quantity * t2.Order_price)
from table2 t2
where t2.Order_id = t1.Order_id) as Total_Sales
from table1 t1;

SQL Multiple INNER JOINS In One Select-Statement

I am using this code for inventory management system, in which i want to retrieve stock in hand from four tables. i have tried with two table and got accurate result as i need it.please help me out.
Table Schema
Productmastertb
prod_id,
Product_name
salesdetailstb
sales_id,
Prod_id,
Prod_qty
estimatedetailstb
est_id,
Prod_id,
Prod_qty
Purchasedetailstb
est_id,
Prod_id,
Prod_qty
Query example (working):
SELECT
productmastertb.prod_id,
productmastertb.prod_name,
sum(estimatedetailstd.prod_qty) as Est_qty
FROM
productmaster
INNER JOIN
estimatedetailstb ON productmastertb.prodid = estimatedetails.prodid
GROUP BY
productmastertb.prod_id, productmastertb.prod_name
Similarly I have to retrieve sum of salesdetailstb.qty and purchasedetailstb.qty
Thanks in advance
You want to summarize across different "dimensions" -- that is tables. One good approach is to aggregate before doing the JOINs. Or to use subqueries. Here is the latter approach:
SELECT pm.prod_id, pm.prod_name,
(SELECT SUM(ed.prod_qty)
FROM estimatedetailstb as ed
WHERE ed.prodid = ed.prodidas
) as Est_qty,
(SELECT SUM(sd.prod_qty)
FROM salesdetailstb as sd
WHERE sd.prodid = pm.prodidas
) as Sales_qty,
(SELECT SUM(pd.prod_qty)
FROM purchasedetailstb as pd
WHERE pd.prodid = pm.prodid
) as Sales_qty
FROM productmaster pm;
This will give you all products, even those missing from one or more of the other tables.
You can add multiple joins.
SELECT t1.id, t4.name, count(t4.name)
FROM Table1 AS t1
INNER JOIN Table2 AS t2 -- the AS statement renames the table within
-- this query to t2. Columns from this table can be used
-- as t2.columnname. This needs to be done when you have
-- columns with the same name in different tables.
ON t1.id = t2.id
INNER JOIN Table3 as t3
ON t1.id = t3.id
INNER JOIN Table4 as t4
ON t3.name = t4.name
GROUP BY t1.id, t4.name

Count records only from left side of a LEFT JOIN

I'm building an Access query with a LEFT JOIN that, among other things, counts the number of unique sampleIDs present in the left table of the JOIN, and counts the aggregate number of specimens (bugs) present in the right table of the JOIN, both for a given group of samples (TripID). Here's the pertinent chunk of SQL code:
SELECT DISTINCT t1.TripID, COUNT(t1.SampleID) AS Samples, SUM(t2.C1 + t2.C2)
AS Bugs FROM tbl_Sample AS t1
LEFT JOIN tbl_Bugs AS t2 ON t1.SampleID = t2.SampleID
GROUP BY t1.TripID
The trouble I'm having is that COUNT(t1.SampleID) is not giving me my desired result. My desired result is the number of unique SampleIDs present in t1 for a given TripID (let's say 7). Instead, what I get seems to be the number of rows in t2 for which the SampleID is contained within the given TripID group (let's say 77). How can I change this SQL query to get the desired number (7, not 77)?
just take the aggregate sum first on t2, then join with t2 like this:
SELECT t1.TripID, COUNT(t1.SampleID) AS Samples, SUM(t3.Bugs) as Bugs
FROM tbl_Sample AS t1
LEFT Join (
SELECT t2.SampleID, SUM(t2.C1 + t2.C2) as Bugs
FROM tbl_Bugs as t2
GROUP BY SampleID) AS t3 ON t1.SampleID = t3.SampleID
GROUP BY t1.TripID
This is a tricky query, because you have different hierarchies. Here is one method:
select s.tripid, count(*) as numsamples,
(select sum(b2.c1 + b2.c2)
from bugs b join
tbl_sample s2
on s2.sampleid = b.sampleid
where s2.tripid = s.tripid
) as numbugs
from tbl_sample s
group by s.tripid
You included a DISTINCT with a Group By. This is removing duplicates twice, which is unnecessarily complex. You can get rid of the DISTINCT.
I would have the count separate from what is going on in the group by.
SELECT dT.TripID
,(SELECT COUNT(DISTINCT(SampleID))
FROM Bugs B
WHERE B.TripID = dT.TripID
) AS [Samples]
,dT.Bugs
FROM (
SELECT t1.TripID
,SUM(t2.C1 + t2.C2) AS Bugs
FROM tbl_Sample AS t1
LEFT JOIN tbl_Bugs AS t2 ON t1.SampleID = t2.SampleID
GROUP BY t1.TripID
) AS dT

Where Exists query returning incorrect results

The inner query here returns values that only appear in one of the tables. The outer query is supposed to return a count of those. Instead, it returns the entire table, not just the NULL values.
select count(*) from tblicd
where exists
(
select i.icd_id
from tblicd i left outer join icd_jxn on icd_jxn.icd_id=i.icd_id
where icd_jxn.icd_id is null
)
The inner query
select i.icd_id
from tblicd i left outer join icd_jxn on icd_jxn.icd_id=i.icd_id
where icd_jxn.icd_id is null
works and does what I want. I'd like (using a sub query method like this) to use the outer query to just return the number of rows that the inner query returns.
You need to join the two (outer and inner) tblicd tables in the subquery:
and i.icd_id = tblicd.icd_id
(or whatever the id of the tblicd table is)
The query you posted doesn't make any sense. However, from your description, it sounds like you've got two tables and you're trying to find any IDs that don't exist in both tables. If that's correct, you should try something like this:
select count(*) as cnt
from table1 t1
full outer join
table2 t2
on t1.id = t2.id
where t1.id is null
or t2.id is null
This may not work in the database you're using, but since you didn't tell us that, we can't tailor the solution to fit your dialect of SQL.
Based on the revised question, you could simplify this a number of ways:
select count(*)
from tblicd
where not exists (select i.icd_id
from icd_jxn
where icd_jxn.icd_id = tblicd)
select count(tblicd.icd_id)
from tblicd
left join
icd_jxn
on tblicd.icd_id = icd_jxn.icd_id
where icd_jxn.icd_id is null
select count(tblicd.icd_id)
from tblicd
where icd_id not in (select icd_id
from icd_jxn)
Basically, there's no reason to select from tblicd twice.

Outer Join with Where returning Nulls

Hi I have 2 tables. I want to list
all records in table1 which are present in
table2
all records in table2 which are not present in table1 with a where condition
Null rows will be returned by table1 in second condition but I am unable to get the query working correctly. It is only returning null rows
SELECT
A.CLMSRNO,A.CLMPLANO,A.GENCURRCODE,A.CLMNETLOSSAMT,
A.CLMLOSSAMT,A.CLMCLAIMPRCLLOSSSHARE
FROM
PAKRE.CLMCLMENTRY A
RIGHT OUTER JOIN (
SELECT
B.CLMSRNO,B.UWADVICETYPE,B.UWADVICENO,B.UWADVPREMCURRCODE,
B.GENSUBBUSICLASS,B.UWADVICENET,B.UWADVICEKIND,B.UWADVYEAR,
B.UWADVQTR,B.ISMANUAL,B.UWCLMNOREFNO
FROM
PAKRE.UWADVICE B
WHERE
B.ISMANUAL=1
) r
ON a.CLMSRNO=r.CLMSRNO
ORDER BY
A.CLMSRNO DESC;
Which OS are you using ?
Table aliases are case sensistive on some platforms, which is why your join condition ON a.CLMSRNO=r.CLMSRNO fails.
Try with A.CLMSRNO=r.CLMSRNO and see if that works
I'm not understanding your first attempt, but here's basically what you need, I think:
SELECT *
FROM TABLE1
INNER JOIN TABLE2
ON joincondition
UNION ALL
SELECT *
FROM TABLE2
LEFT JOIN TABLE1
ON joincondition
AND TABLE1.wherecondition
WHERE TABLE1.somejoincolumn IS NULL
I think you may want to remove the subquery and put its columns into the main query e.g.
SELECT A.CLMSRNO, A.CLMPLANO, A.GENCURRCODE, A.CLMNETLOSSAMT,
A.CLMLOSSAMT, A.CLMCLAIMPRCLLOSSSHARE,
B.CLMSRNO, B.UWADVICETYPE, B.UWADVICENO, B.UWADVPREMCURRCODE,
B.GENSUBBUSICLASS, B.UWADVICENET, B.UWADVICEKIND, B.UWADVYEAR,
B.UWADVQTR, B.ISMANUAL, B.UWCLMNOREFNO
FROM PAKRE.CLMCLMENTRY A
RIGHT OUTER JOIN PAKRE.UWADVICE B
ON A.CLMSRNO = B.CLMSRNO
WHERE B.ISMANUAL = 1
ORDER
BY A.CLMSRNO DESC;