oracle sql error:distinct case - sql

I am trying to select a distinct column from an oracle database,my code is:
select ID,distinct case when DM='ST1B' then MC else DM end from D_DZDY
but,it does not work.If i remove 'distinct',it works:
enter image description here
Anybody can help me with this problem?thanks a lot! :D

The syntax is select distinct. There is no distinct function or operator on a single column.
Perhaps you intend:
select distinct ID, (case when DM = 'ST1B' then MC else DM end)
from D_DZDY;
This will return distinct pairs of id and the case expression.

DISTINCT OPERATE ON ROW, YOU SHOULD USE THIS SYNTAX :
select distinct ID,(case when DM='ST1B' then MC else DM end) from D_DZDY
IF YOU JUST WANT DEFERMENT VALUES OF THE CASE STATEMENT YOU COULD USE THIS
select distinct (case when DM='ST1B' then MC else DM end) from D_DZDY

Related

How to check unique values in SQL

I have a table named Bank that contains a Bank_Values column. I need a calculated Bank_Value_Unique column to shows whether each Bank_Value exists somewhere else in the table (i.e. whether its count is greater than 1).
I prepared this query, but it does not work. Could anyone help me with this and/or modify this query?
SELECT
CASE
WHEN NULLIF(LTRIM(RTRIM(Bank_Value)), '') =
(SELECT Bank_Value
FROM [Bank]
GROUP BY Bank_Value
HAVING COUNT(*) = 1)
THEN '0' ELSE '1'
END AS Bank_Key_Unique
FROM [Bank]
A windowed count should work:
SELECT
*,
CASE
COUNT(*) OVER (PARTITION BY Bank_Value)
WHEN 1 THEN 1 ELSE 0
END AS Bank_Value_Unique
FROM
Bank
;
It works also, but I found solution also:
select CASE WHEN NULLIF(LTRIM(RTRIM(Bank_Value)),'') =
(select Bank_Value
from Bank
group by Bank_Value
having (count(distinct Bank_Value) > 2 )) THEN '1' ELSE '0' END AS
Bank_Value_Uniquness
from Bank
It was missing "distinct" in having part.

How to combine CASE statement with Inner Join for Alphanumeric OrderBY

In this query, I am trying to select all distinct (alphanumeric) machine names and order them correctly (1,2,5,10,15 instead of 1,10,15,2,5). The CASE statement is proven to work when the LocalName is not joined by INNER JOIN, so I suspect this is where the problem lies.
SELECT DISTINCT MCGroup, VisionMachinePerformance.MCSAP, ZAssetRegister.LocalName
FROM [VisionMachinePerformance] INNER JOIN ZAssetRegister ON VisionMachinePerformance.MCSAP=ZAssetRegister.SAP_Number
ORDER BY
CASE WHEN PATINDEX('%[0-9]%',LocalName) > 1 THEN
LEFT(LocalName,PATINDEX('%[0-9]%',LocalName)-1)
ELSE LocalName END ,
CASE WHEN PATINDEX('%[0-9]%',LocalName) > 1 THEN
CAST(SUBSTRING(LocalName,PATINDEX('%[0-9]%',LocalName),LEN(LocalName)) as float)
ELSE NULL END
The error that is reported is "SQL Error (145): ORDER BY items must appear in the select list if SELECT DISTINCT is specified".
I have tried changing all references in the CASE statement to ZAssetRegister.LocalName and VisionMachinePerformance.LocalName without success.
Removing all of the CASE statement and ordering by LocalName does work, but with the wrong order as mentioned above (1,10,15,2,5).
Could anybody suggest how to make this work?
TIA!
You can separate both parts using a subquery:
SELECT * FROM (
SELECT DISTINCT MCGroup, VisionMachinePerformance.MCSAP, ZAssetRegister.LocalName
FROM [VisionMachinePerformance]
INNER JOIN ZAssetRegister ON VisionMachinePerformance.MCSAP=ZAssetRegister.SAP_Number
) DISTINCT_DATA
ORDER BY
CASE WHEN PATINDEX('%[0-9]%',LocalName) > 1
THEN LEFT(LocalName,PATINDEX('%[0-9]%',LocalName)-1)
ELSE LocalName END,
CASE WHEN PATINDEX('%[0-9]%',LocalName) > 1
THEN CAST(SUBSTRING(LocalName,PATINDEX('%[0-9]%',LocalName),LEN(LocalName)) as float)
ELSE NULL END

Using SQL SUM with Case statement containing inner SELECT

I have two tables, an Orders table which contains a list of a users orders and a OrderShippingCosts table which contains a price for shipping each item based on the OrderTypeID in the Orders table.
I am running a query like below to calculate the total shipping costs:
SELECT
SUM(CASE
WHEN OR.OrderTypeID = 1
THEN (SELECT CostOfShippingSmallParcel
FROM OrderShippingCosts)
ELSE (SELECT CostOfShippingBigParcel
FROM OrderShippingCosts)
END) AS TotalShippingCost
FROM
Orders AS OR
But I'm getting the following error:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery
Does anyone know what is wrong with my query?
Function SUM takes an expression on input, which evaluates into single data value, not a dataset. Expression definition from MSDN:
Is a combination of symbols and operators that the SQL Server Database Engine evaluates to obtain a single data value.
You trying to pass to SUM function a dataset (which is result of subquery), not a single data value. This is simplification of what you trying to query:
SELECT SUM(SELECT Number FROM SomeTable)
It is not valid. The valid query would be:
SELECT SUM(Value) FROM SomeTable
In your particular case looks like you missing JOIN. Your original logic will result in summary of entire OrderShippingCosts table for each row of Orders table. I think, it should be something like this:
SELECT
SUM
(
CASE
WHEN ord.OrderTypeID = 1 THEN ship.CostOfShippingSmallParcel
ELSE ship.CostOfShippingBigParcel
END
) TotalShippingCost
FROM Orders AS ord
JOIN OrderShippingCosts ship ON /* your search condition, e.g.: ord.OrderID = ship.OrderID */
By the way, it is not a good idea to use reserved symbols as aliases, names and so on. In your query you use OR as alias for Orders table. Symbol OR is reserved for logical or operation. If you really need to use reserved symbol, wrap it into [ and ] square braces. Look here and here for more details.
The error message is clear, you can avoid it with a join:
SELECT
SUM(CASE WHEN [OR].OrderTypeID = 1
THEN CostOfShippingSmallParcel
ELSE CostOfShippingBigParcel END) AS TotalShippingCost
FROM Orders [OR]
CROSS JOIN OrderShippingCosts
You can try like this...
SELECT
CASE WHEN OR.OrderTypeID = 1
THEN (SELECT SUM(CostOfShippingSmallParcel) FROM OrderShippingCosts)
ELSE (SELECT SUM(CostOfShippingBigParcel) FROM OrderShippingCosts) END AS TotalShippingCost
FROM Orders AS OR
Let me know
select sum (or.TotalShippingCost)
FROM
SELECT
(CASE WHEN OR.OrderTypeID = 1
THEN (SELECT CostOfShippingSmallParcel FROM OrderShippingCosts)
ELSE (SELECT CostOfShippingBigParcel FROM OrderShippingCosts) END) AS TotalShippingCost
FROM Orders AS OR
Try this
SELECT
ISNULL
(
SUM
(
CASE
WHEN O.OrderTypeID = 1 THEN C.CostOfShippingSmallParcel
ELSE C.CostOfShippingBigParcel END
), 0
) AS TotalShippingCost
FROM
Orders AS O LEFT JOIN
OrderShippingCosts C ON O.Id = C.OrderId -- Your releation id

How to use CASE without adding new column to table in SQL

How to change column value by CASE command depending on condition without giving adding a new column to table?
The only way I know is by adding new column:
SELECT
t1.*
,CASE
what='costs' THEN amount*(-1)
ELSE
sales
END AS NewAmount
FROM t1
Is there a way to get the results as on the picture below? Note that sometimes the condition is specified by values in more than one column (what=costs AND country=Atlantida)
Select just the columns that you want:
SELECT t1.what,
(CASE WHEN what = 'costs' THEN amount*(-1)
ELSE sales
END) AS Amount
FROM t1
Yes, there is way,
Instead of select *, use required column names only.
SELECT
t1.what
,CASE
WHEN what='costs' THEN amount*(-1)
ELSE
sales
END AS Amount
FROM t1
Don't you want amount when not cost?
SELECT
t1.*
,CASE when what='costs' THEN amount*(-1)
ELSE
amount
END AS NewAmount
FROM t1

CASE SQL Oracle Query - What is wrong?

I have following query to select the view to be used in the query, however I get the error:
FROM keyword not found where expected
select *, (CASE WHEN 'employee' = 'employee' THEN employee ELSE vw END) FROM type1
select type1.*,
(CASE WHEN 'employee' = 'employee'
THEN employee
ELSE vw
END)
FROM type1
I always prefix with the tablename/table alias to the * and it works!!
We just need to specify, fetch all the column from this table, when we specify combination of wildcard and other select expressions!
You cannot use * and individual columns together in select statement.
SELECT (CASE WHEN 'employee' = 'employee' THEN 'employee' ELSE 'vw' END)
FROM dual
You cant do a *, in Oracle without an alias/TableName(.) in front of it. List out the columns you want to see in the result set or add a table alias/tablename.
You cannot set the name of the view the select statement shall retrieve data from in the column list part of the statement.