group by expression must contain one column that is not an outer reference - sql

Would somebody please take a look at this? I am trying to sum the total weight of all of our skus, but I need them to group either by foreign or domestic. SQL 2008 server.
Select
IMSYS01.on_hand_qty * IMSYS01.piece_weight,
IMSYS01.sku_no,
case when(imsys01.warehouse = '109') then 'foreign' else 'domestic' end as 'vLocation'
From
IMSYS01 IMSYS01
Where
(IMSYS01.sku_no < '99999' And
IMSYS01.velo_code <> 'X')
Group By
IMSYS01.on_hand_qty * IMSYS01.piece_weight, 'vLocation', IMSYS01.sku_no

Oh, the dreaded use of single quotes for an identifier. Don't use single quotes for an identifier. This is what you want:
Select IMSYS01.on_hand_qty * IMSYS01.piece_weight,
IMSYS01.sku_no,
(case when(imsys01.warehouse = '109') then 'foreign' else 'domestic' end) as vLocation
From IMSYS01 IMSYS01
Where (IMSYS01.sku_no < '99999' And IMSYS01.velo_code <> 'X')
Group By IMSYS01.on_hand_qty * IMSYS01.piece_weight,
(case when(imsys01.warehouse = '109') then 'foreign' else 'domestic' end),
IMSYS01.sku_no;
This is a great example of why you should never use single quotes for identifiers. It causes confusion. SQL Server supports other methods, but you don't even need to escape vlocation. It is a fine identifier just by itself.

Related

SQL CASE Expression

I need to write a sql statement(Oracle) where I can withdraw data from two diff tables and check for a condition and return a certain string.
My statement goes like this,
Select review.comments as comments,resort.resortid,resort.resortname
case review.comments
when resort.starrating>=4.5 and resort.starrating<5 then 'Excellent'
when resort.strarating>=4 and resort.starrating<4.5 then 'Great'
else 'Good'
end
from review, resort
order by resort.resortid;
When I run this I get a error: "FROM keyword not found where expected"and points to the c in line 2.
and if I change the from to line 2, it gives error: "SQL command not properly ended". and points to line 3 r in "case review.comments"
You need a JOIN, aggregation, and to fix the CASE expression syntax. I assume you want something like this:
Select res.resortid, res.resortname,
(case when avg(rev.starrating) >= 4.5 then 'Excellent'
when avg(rev.starrating) >= 4 then 'Great'
else 'Good'
end) as category
from review rev join
resort res
on rev.resortid = res.resortid
group by res.resortid, res.resortname
order by res.resortid;
You're mixing two variants of the case syntax. If you're going to supply conditions (not just values), you shouldn't have an expression following the case keyword:
case -- review.comments should be removed from here
when resort.starrating>=4.5 and resort.starrating<5 then 'Excellent'
when resort.strarating>=4 and resort.starrating<4.5 then 'Great'
else 'Good'
end
Syntax for case is
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END;
so your code should look like this..
SELECT review.comments AS comments,
resort.resortid,
resort.resortname,
CASE
WHEN resort.starrating >= 4.5
AND resort.starrating < 5 THEN 'Excellent'
WHEN resort.strarating >= 4
AND resort.starrating < 4.5 THEN 'Great'
ELSE 'Good'
END
FROM review,
resort
ORDER BY resort.resortid;
Also just for your information, The comma between the two tables signifies a CROSS JOIN.
So your query is equivalent to:
select * from
FROM review
CROSS JOIN resort

Select with IF statement on postgresql

I have a code like that:
select
tbl.person
,COUNT(distinct tbl.project)
,if (tbl.stage like '%SIGNED%') then sum(tbl.value) else '0' end if as test
from
my_table tbl
group by
1
And it returns me that error message:
SQL Error [42601]: ERROR: syntax error at or near "then"
I didn't got it. As I saw on documentation, the if statement syntax appears to be used correctly
IF is to be used in procedures, not in queries. Use a case expression instead:
select
tbl.person
,COUNT(distinct tbl.project)
,sum(case when tbl.stage like '%SIGNED%' then tbl.value else 0 end) as test
from
my_table tbl
group by
1
Notes:
tbl.stage is not part of the group by, so it should most probably be enclosed within the aggregate expression, not outside of it
all values returned by a case expression need to have the same datatype. Since sum(tbl.value) is numeric, the else part of the case should return 0 (number), not '0' (string).
In Postgres, I would recommend using filter:
select tbl.person, COUNT(distinct tbl.project)
sum(tbl.value) filter (where tbl.stage like '%SIGNED%') as test
from my_table tbl
group by 1;
if is control flow logic. When working with queries, you want to learn how to think more as sets. So the idea is to filter the rows and add up the values after filtering.
replace
if (tbl.stage like '%SIGNED%') then sum(tbl.value) else '0' end if as test
with
sum(case when tbl.stage like '%SIGNED%' then tbl.value end) as test

Using function inside CASE

I am trying to use the SUBSTR and NVL functions inside the case. The case is in the where clause of the select statement.
The code below gives the following error:
ORA-00905: missing keyword
AND ( CASE
WHEN SUBSTR(upper(p_open_invoice),1,1) = 'Y' THEN
NVL(P.AMOUNT_DUE_REMAINING,0) = 0
ELSE
1=1
END)
This looks like a syntax error around equal operator of NVL function.
That is not how case expressions work (in Oracle) -- there is no boolean type to return.
The simplest method is to remove the `case and express this as simple logic:
AND (SUBSTR(upper(p_open_invoice), 1, 1) <> 'Y' OR
COALESCE(P.AMOUNT_DUE_REMAINING, 0) = 0
)
If p_open_invoice can be NULL, you need to take that into account as well.
You cannot use a collation as a result for case..when statements, it's better converting the condition to
AND (( SUBSTR(upper(p_open_invoice),1,1) = 'Y' AND NVL(P.AMOUNT_DUE_REMAINING,0) = 0 )
OR SUBSTR(upper(p_open_invoice),1,1) != 'Y' )
If you're accustomed to programming in PL/SQL you may have seen that there's a BOOLEAN type in PL/SQL. However, this is not true in the Oracle database itself. The way I usually work around this is to use character expressions which return 'Y' or 'N' instead of TRUE or FALSE.
Keeping this in mind - if you really want to use a CASE expression similar to what you had originally you can use the following:
AND CASE
WHEN SUBSTR(upper(p_open_invoice),1,1) = 'Y'
THEN CASE
WHEN NVL(P.AMOUNT_DUE_REMAINING,0) = 0 THEN 'Y'
ELSE 'N'
END
ELSE 'Y'
END = 'Y'
Here the CASE expression returns either 'Y' or 'N', which is then compared with 'Y'.

sql syntax is not working with group by clause

i am writing sql and I am stuck in the following line
select employeeid, (case paidL when'1'
Then
1
when '0'
Then
0
end) as 'paidLeave' from Lea order by employeeid group by 'paidLeave'
The above line if giving me error related to 'paidLeave'
Any help to improve the syntax to remove the error will be appreciated
Your case syntax is obviously wrong. But you have another error: Never use single quotes for column aliases. This is an example of an error waiting to happen.
It is best to use column and table names that do not need to be escaped. If they do, use square braces or double quotes.
The query you want should look like this:
select employeeid,
(case when paidL = '1' then 1
when paidl = '0 then 0
end) as paidLeave
from Lea
order by employeeid;
I have no idea what group by 'paidleave' is supposed to do. It is syntactically wrong on two fronts. If you want the sum, then the query would be something like:
select employeeid,
sum(case when paidL = '1' then 1
when paidl = '0 then 0
end) as paidLeave
from Lea
group by employeeid;
I think you need to study up on basic SQL syntax. There are many resources on the web and in books.
Your case syntax is all wrong, use this :
select employeeid, (case when paidL = '1'
Then 1
when paidL = '0'
Then 0
end) as paidLeave
from Lea
order by employeeid
Also, order by comes after group by!
Another thing, quote marks are used for strings, not column names. Maybe you meant ` but you don't have to do this because this is not a reserved word.
This whole query seems wrong, the group by doesn't make any sense if you have more then one employee, maybe you meant to group by emplooyeid and order by paidleave?
Maybe you meant to group by employee id and select the maximm paidLeave? in this case:
select employeeid, max((case when paidL = '1'
Then 1
when paidL = '0'
Then 0
end)) as paidLeave
from Lea
group by employeeid
order by employeeid
The CASE syntax is incorrect, it should follow the form;
CASE
WHEN <condition> THEN <result>
... (multiples of WHEN ... THEN ...)
ELSE <result>
END [Alias]
So something like;
CASE
WHEN [paidL] = '1' THEN 1
WHEN [paidL] = '0' THEN 0
END [paidLeave]
First of all, to better help you should provide the error. However, at first sight I would say your error is, you do not have included the employeeid column as part of the GROUP BY. Also I won't use a CASE statement for something you can resolve with casting. You could either CAST the paidL column to either INT or to BIT (just if values are only 0/1).
CAST([paidL] AS INT) paidL
CAST([paidL] AS BIT) paidL

Return 'Yes' or No' from select statement?

tbl_LoanSummary has Sample_Number column. I have to check if Sample_Number column is not null the return 'Y' otherwise return return 'N' from below select statement.
select a.Br_Loan_No ,a.Br_LookupKey, //return IsNull(s.Sample_Number) ='N' or 'Y'
from dbo.tbl_Br a left outer join dbo.tbl_LoanSummary s
on s.Loan_no = a.Br_Loan_No order by a.Br_Loan_No
How to do this?
You can use the case expression for this...
select a.Br_Loan_No,
a.Br_LookupKey,
CASE WHEN s.Sample_Number IS NULL THEN 'N' ELSE 'Y' END AS [HasSample]
from dbo.tbl_Br a left outer join dbo.tbl_LoanSummary s
on s.Loan_no = a.Br_Loan_No order by a.Br_Loan_No
In Oracle, you could also use
select NVL(s.Sample_Number, 'N')
to return N in case of null value
(of course you still need something to have Y in case of not null.)
You'll want to use a CASE expression. It's like an embedded if-statement or switch-statement from traditional programming languages.
SELECT a.Br_Loan_No,
a.Br_LookupKey
CASE
WHEN s.Sample_Number IS NULL THEN 'N'
ELSE 'Y'
END AS sample_number_is_not_null
FROM dbo.tbl_Br a
LEFT JOIN dbo.tbl_LoanSummary s
ON s.Loan_no = a.Br_Loan_No
ORDER BY a.Br_Loan_no
Note that you are creating a computed column here, rather than selecting the raw value of an existing column. It's generally required that you give this column a name, thus the use of the AS sample_number_is_not_null.
There are two forms of the CASE expression. One lets you compare a column or value against several choices. It is like using an implicit equals:
CASE foo
WHEN 3 THEN 'foo is 3!'
WHEN 4 THEN 'foo is 4!'
ELSE 'foo is not 3 or 4'
END
The other form, in the example at the top, lets you use arbitrary expressions in each WHEN clause. It should be noted that each WHEN clause is evaluated in order and the first one to match is the one whose THEN is used as the result. If none of the WHENs match, then the result in the ELSE is used.