Can't figure out how to modify this oracle query - sql

I've got a query over here that I need to modify, but I can't figure out how.
I only want to show the color (aka kleur) where aantal_planten is lower than five.
Any suggetions?
Here's the query:
SELECT kleur, COUNT(plant.plantcode) AS aantal_planten
FROM plant, offerte
WHERE plant.plantcode = offerte.plantcode
GROUP BY kleur;
Here's the database structure

You should learn proper explicit JOIN syntax. Simple rule: Never use commas in the FROM clause. Always use explicit JOIN syntax.
The answer to your question is a HAVING clause:
SELECT kleur, COUNT(p.plantcode) AS aantal_planten
FROM plant p JOIN
offerte o
ON p.plantcode = o.plantcode
GROUP BY kleur
HAVING COUNT(p.plantcode) < 5;
Also notice that table aliases makes the query easier to write and to read.

Related

SQL - with only showing a value greater than 0

I am fairly new to SQL. I have my code written out where I display a Vendor name and the total amt due for all of their invoices. My issue is, I only need to display those Vendors that has a total greater than $0.00. Any insight would be greatly appreciated.
SELECT DISTINCT VENDOR_NAME, TO_CHAR(SUM(INVOICE_TOTAL-PAYMENT_TOTAL-CREDIT_TOTAL), '$999,999.99') AS AMTDUE
FROM AP.VENDORS, AP.INVOICES
WHERE AP.VENDORS.VENDOR_ID = AP.INVOICES.VENDOR_ID
GROUP BY VENDOR_NAME;
Code displays:
Use a having clause:
SELECT VENDOR_NAME,
TO_CHAR(SUM(INVOICE_TOTAL-PAYMENT_TOTAL-CREDIT_TOTAL), '$999,999.99') AS AMTDUE
FROM AP.VENDORS V JOIN
AP.INVOICES I
ON V.VENDOR_ID = I.VENDOR_ID
GROUP BY VENDOR_NAME
HAVING SUM(INVOICE_TOTAL - PAYMENT_TOTAL-CREDIT_TOTAL) > 0;
Notes:
Never use commas in the FROM clause.
Always use proper, explicit, standard, readable JOIN syntax.
Use table aliases.
Qualify all column names. I don't know where they come from, but I would guess most should be preceded by I..

CASE Statment and IN() Operator in JOIN Condition

I'm trying to create a join that follows the following logic:
If our company is the Plaintiff, join to the following role types in
the table: Defense Firm, Defense Attorney
If our company is the Defendant, join to the following role types in
the table: Plaintiff Firm, Plaintiff Attorney
So far, I have this code written in the join, but it always produces an error for every syntax I've tried:
WHERE
TRIAL.TRIAL_ID = OPPOSITION.TRIAL_ID
AND OPPOSITION.ROLE IN
CASE
WHEN TRIAL.POSITION = 'Plaintiff'
THEN ('Defense Firm','Defense Attorney' )
WHEN TRIAL.POSITION = 'Defendant'
THEN ('Plaintiff Firm','Plaintiff Attorney')
END
We are currently running on Oracle (??)g.
Is this sort of join logic even possible?
EDITS:
Fixed the Defendant/Plaintiff mixup in the code section
Not sure what version of Oracle we're on.
You can use AND/OR logic, with appropriate parenthetical grouping, to achieve this (if I'm following what you need), something like:
WHERE TRIAL.TRIAL_ID = OPPOSITION.TRIAL_ID
AND (
(TRIAL.POSITION = 'Plaintiff'
AND OPPOSITION.ROLE IN ('Defense Firm', 'Defense Attorney')
OR
(TRIAL.POSITION = 'Defendant'
AND OPPOSITION.ROLE IN ('Plaintiff Firm', 'Plaintiff Attorney')
)
Although these look like they should be part of an ANSI JOIN clause, rather than a WHERE clause...

Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

I'm trying to select a bunch of patients with their unit and division and I want to group the result by unit name, but this code doesn't execute and gives the error as the topic of this question.
SELECT TOP (100) PERCENT
Pat.PatName AS Name,
srvDiv.sgMType AS Perkhidmatan,
Pat.PatMRank AS Pangkat,
Pat.PatMilitaryID AS [No# Tentera],
unt.untName AS Unit,
fct.pesStatusCode as StatusCode,
fct.pesSignedDate AS SignedDate
FROM dbo.FactPES AS fct INNER JOIN
dbo.DimPatient AS Pat ON fct.pesPatID = Pat.PatID LEFT OUTER JOIN
dbo.DimUnit AS unt ON fct.pesUnitID = unt.untID LEFT OUTER JOIN
dbo.DimServiceDiv AS srvDiv ON fct.pesServiceDivID = srvDiv.sgID
GROUP BY unt.untName
HAVING (deas.diDate BETWEEN
CONVERT(DATETIME, #FromDate, 102)
AND
CONVERT(DATETIME, #ToDate, 102))
I assume it's because unt.UntName is in my left join so I can't use it outside the join maybe ? I'm a bit confused because when I put it like this it works:
GROUP BY unt.untName, Pat.PatName, srvDiv.sgMType,
Pat.PatMRank, Pat.PatMilitaryID, unt.untName,
fct.pesStatusCode, fct.pesSignedDate
Any help is appreciated
First, please don't use TOP (100) PERCENT; it hurts even to read.
Second, your query contains no aggregate function, no SUM or COUNT for example. When you say you want to "group by unit name", I suspect you may simply want the results sorted by unit name. In that case, you want ORDER BY instead. (The advice from other to study what group by does is well taken.)
Finally, you might not need those CONVERT functions at the end, depending on your DBMS.
Whenever you use a GROUP BY - it should be present in the SELECT statement as a column. And if you do not want to contain it in a GROUP BY use it as an AGGREGATE column in SELECT.
So now in your case the second GROUP BY stated in your question will work.
Read this to understand more about GROUP BY

Oracle SQL - Left join on "in" statements

The point of the query below is to return a list of people and whether or not they are unhappy. But, If I don't know if they are happy or not, I want to list their name and their unhappy as "happy". This is complicated by the fact that I have some additional requirements for what defines unhappy.
I'm writing a query like this...
Select name.firstName,
CASE
WHEN Mood.mood is not null
THEN 'Unhappy'
ELSE 'Happy'
END Unhappy
From name
Mood
WHERE mood.firstName(+) = name.firstName
AND mood.type IN ('Hungry','Tired','Fatigued','Bored',null)
AND mood.value(+) > 5;
So I want to return every single name from the table name, and either a value of "happy" or "unhappy", even though those names may or may not be in mood table. When I run this as I've written it, I get no rows. I figure this might involve my mood.type line because I can't use a left join on an "in" statement.
I think you have a couple of problems:
You have a spurious semi-colon in your WHERE clause.
The CASE expression is in the wrong place.
You shouldn't use NULL in an IN expression.
You could remove the semi-colon and change your IN expression to this instead:
AND (mood.type IN ('Hungry','Tired','Fatigued','Bored') OR mood.type IS NULL)
Also, I'd strongly advise you not to use that obsolete join syntax. It's probably a good idea to use the JOIN keyword as it makes this sort of query a lot easier.
SELECT
name.firstName,
CASE
WHEN Mood.mood IS NOT NULL
THEN 'Unhappy'
ELSE 'Happy'
END Unhappy
FROM name
LEFT JOIN Mood ON
mood.firstName = name.firstName AND
mood.type IN ('Hungry','Tired','Fatigued','Bored') AND
mood.value > 5
I would do it like this:
select n.firstname,
nvl(m.mood, 'Happy') mood
from
name n
left outer join mood m
on n.firstname = m.firstname
where
nvl(m.type,'Hungry') in ('Hungry', 'Tired', 'Fatigued', 'Bored')

sql query question inner join

LEFT JOIN PatientClinics AB ON PPhy.PatientID = AB.PatientID
JOIN Clinics CL ON CL.ID = AB.ClinicID
AND COUNT(AB.ClinicID) = 1
I get error using Count(AB.ClinicID) = 1 (ClinicID has duplicate values in the table and
I want to use only 1 value of each duplicate value of ClinicId to produce result)
What mistake am I making?
I've never seen a COUNT() being used in a JOIN before. Maybe you should use:
HAVING COUNT(AB.ClinicID) = 1
instead.
Count() can't be used as a join/filter predicate. It can be used in the HAVING clause however. You should include the entire query in order to get a better example of how to rewrite it.
maybe investigate the HAVING clause instead of using COUNT where you put it.
hard to help without the full query.