I am new to Oracle :)
I have this statement has a string value called Active. The value can be Y or N. I want to do a select statement that returns a boolean value for that field.
Currently it looks like this:
select h.catalogueid ID,
h.cataloguename NAME,
h.uniquecatalogue INCLUDEPRODUCTS,
h.active ACTIVE,
h.ownbrandedlabels OWNLABELS
from cc_ob_catalogueheader h
I would like to do something like this:
select h.catalogueid ID,
h.cataloguename NAME,
h.uniquecatalogue INCLUDEPRODUCTS,
h.active = 'Y' ACTIVE,
h.ownbrandedlabels OWNLABELS
from cc_ob_catalogueheader h
But that is syntaxly incorrect. Does anyone know how I can do this?
I solved this myself.
I changed my select statement to this:
select h.catalogueid ID,
h.cataloguename NAME,
h.uniquecatalogue INCLUDEPRODUCTS,
CASE WHEN (h.active = 'Y') THEN 1 ELSE 0 END ACTIVE,
h.ownbrandedlabels OWNLABELS
from cc_ob_catalogueheader h
Related
I get on oracle-server ORA-01732.
There are any other issues with this ORA, but it does not help me on my situation.
I select typicaly some data from two tables and i group these something like this:
SELECT SUM (LG_ALL.HOURS) AS hour_sum,
TO_CHAR (LG_ALL.WORK_DATE, 'YYYY.MM') AS singel_month,
LG_ALL.EXPORTED
FROM USER usr,
USER_ALLWC LG_ALL,
WHERE usr.user_id = LG_ALL.user_id
AND LG_ALL.EXPORTED = 'N'
GROUP BY
TO_CHAR (LG_ALL.WORK_DATE, 'YYYY.MM'),
LG_ALL.EXPORTED
ORDER BY usr.LOGNAME DESC
At next step, I have to set on table USER_ALLWC:
LG_ALL.EXPORTED = 'Y'
Because of this, i wrap this into update-statement like
updates-based-on-queries => Inline View Method:
UPDATE ( SELECT SUM (LG_ALL.HOURS) AS hour_sum,
TO_CHAR (LG_ALL.WORK_DATE, 'YYYY.MM') AS singel_month,
LG_ALL.EXPORTED
FROM USER usr,
USER_ALLWC LG_ALL,
WHERE usr.user_id = LG_ALL.user_id
AND LG_ALL.EXPORTED = 'N'
GROUP BY
TO_CHAR (LG_ALL.WORK_DATE, 'YYYY.MM'),
LG_ALL.EXPORTED
ORDER BY usr.LOGNAME DESC ) allg
SET allg.EXPORTED = 'Y';
Sadly I get ORA-01732.
Can anyone explain, when I can update on select-statement and how can I fix it?
From Oracle SQL Language Reference:
The view must not contain any of the following constructs:
A set operator
A DISTINCT operator
An aggregate or analytic function
...
Try simplifying it - the sum, group by etc. add no value anyway:
UPDATE ( SELECT LG_ALL.EXPORTED
FROM USER usr,
USER_ALLWC LG_ALL,
WHERE usr.user_id = LG_ALL.user_id
AND LG_ALL.EXPORTED = 'N'
) allg
SET allg.EXPORTED = 'Y';
As long as there is a foreign key from USER_ALLWC to USER this should work.
In fact, assuming there is such a foreign key the whole statement is equivalent to:
UPDATE USER_ALLWC
SET EXPORTED = 'Y'
WHERE EXPORTED = 'N';
I have a query that I need for it to return a record even when there are no records. In the case where there are records, I simply want those records returned. On the other hand, when there are no records, I need it to still return a record but with the value for the "context" column (the GROUP BY column) equal to the value of the GROUP BY column that did not meet the criteria and a default value for aggregate function/column (e.g., 0). I tried a subquery:
SELECT
(
SELECT
CONTEXT,
SUM(VAL)
FROM
A_TABLE
WHERE
COL = 'absent'
GROUP BY
CONTEXT
)
FROM
DUAL;
but anything greater than one column in the subquery SELECT clause fails w/ a "too many values" message.
I also tried a UNION (with a little more context to more faithfully represent my situation):
SELECT
*
FROM
(
SELECT
CONTEXT,
SUM(VAL)
FROM
A_TABLE
WHERE
COL = 'absent'
GROUP BY
CONTEXT
UNION
SELECT
CONTEXT,
0
FROM
B_TABLE
)
AB_TABLE
INNER JOIN C_TABLE C -- just a table that I need to join to
ON
C.ID = AB_TABLE.C_ID
WHERE
C.ID = 10
AND ROWNUM = 1 -- excludes 2nd UNION subquery result when 1st returns record;
This one does work but I don't know why since the 2nd UNION subquery does not seem to be expressly connected w/ the first (I need the 2nd CONTEXT value to be the same as the 1st for the case where the 1st returns no records). The problem is that the real query does not return any records when I try to implement a similar strategy. I would like to see if there's a better way to approach this problem and perhaps get it to work for the real query (not included as it is too large and somewhat sensitive).
I am not sure I understand the question, but let's try.
I believe what you are saying is this. You have a table called A_TABLE, with columns CONTEXT, VAL, COL (and perhaps others as well).
You want to group by CONTEXT, and get the sum of VAL but only for those rows where COL = 'absent'. Otherwise you want to return a default value (let's say 0).
This can be done with conditional aggregation. The condition is in a CASE expression within the SUM, not in a WHERE clause (as you saw already, if you filter by COL='absent', in a WHERE clause, the query - past the WHERE clause - has no knowledge of the CONTEXT values that don't appear in any rows with COL = 'absent').
If the "default value" was NULL, you could do it like this:
select context, sum(case when col = 'absent' then value end) as val
from a_table
group by context
;
If the default value is anything other than NULL, the temptation may be to use NVL() around the sum. However, if VAL may be NULL, then it is possible that SUM(VAL) is NULL even when there are rows with COL = 'absent'. To address that possibility, you must leave the sum as NULL in those cases, and instead set the value to 0 (or whatever other "default value") only when there are NO rows with COL = 'absent'. Here is one way to do that. Still a standard "conditional" aggregate query:
select context,
case when count(case when col = 'absent' then 1 end) > 0
then sum(case when col = 'absent' then value end)
else 0 -- or whatever "default value" you must assign here
end as val
from a_table
group by context
;
Here's another way you could handle it that avoids the two additional tables (B_TABLE and C_TABLE).
SELECT context
, MAX(val)
FROM (
SELECT context
, SUM(val) as val
FROM a_table
WHERE col = 'absent'
GROUP BY context
UNION
SELECT context
, 0 as val
FROM a_table
) t
GROUP BY context
This assumes the default value you want to return is 0 and that any value in A_TABLE.VAL will be a positive integer.
http://sqlfiddle.com/#!4/c6ca0/20
SELECT b.context
, sum(a.val)
FROM b_table b
LEFT OUTER JOIN a_table a
ON a.context = b.context
AND a.col = 'absent'
GROUP BY b.context
How do I return data out of IF statements? I have a IF statement which is meant to return a different result dependent of the result of that statement.
IF :Value = 1 THEN
SELECT Name FROM TABLE_A
ELSEIF :Value = 2 THEN
SELECT Name FROM TABLE_B
ELSEIF :Value = 3 THEN
SELECT Name FROM TABLE_C
but this doesn't work. It expects an INTO statement in those selects. I suspect this is because Oracle can't return out of a block?
Is there a quicker way to return those select statements without creating table variables to store the data or messing around with functions?
You can do this by plain SQL:
SELECT
':Value' user_input,
CASE
WHEN ':Value' IN('a1','a2','a3')
THEN (select name from table_a)
WHEN ':Value' = 'i'
THEN (select name from table_b)
END AS output
FROM
dual
(good info about case)
If you want more than one result in your cases, then you may opt to an intelligent UNION:
SELECT t1_Col_1, t1_Col_2,'&VALUE' from TABLE_1
WHERE '&VALUE' = '1'
UNION ALL
SELECT t2_Col_1, t2_Col_2,'&VALUE' from TABLE_2
WHERE '&VALUE' = '2'
In this solution, types and number of tx_Coln must be the same.
I have this example code of something I'm trying to run. Only he table names and column names were changed. What I want to do is have a result set of states and have 'NULL' be the first value and the rest of the results appear below 'NULL' in ascending order and I can't for the life of me make it work. I get the error at the bottom. This may be a very "noobish" question, but can anyone help? Much appreciated everyone!
SELECT DISTINCT
State
FROM TABLE1 (NOLOCK)
WHERE COLUMN1 NOT LIKE '%THAT%'
AND COLUMN1 NOT LIKE '%THIS%'
UNION
SELECT 'NULL'
ORDER BY ( CASE WHEN State = 'NULL' THEN 0
ELSE 1
END );
Error Message:
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.
You need to select that column... even if you don't use it later, the order by requires it to be present in the select.
SELECT DISTINCT
State,
CASE WHEN State = 'NULL' THEN 0
ELSE 1 END orderId
FROM TABLE1 (NOLOCK)
WHERE COLUMN1 NOT LIKE '%THAT%'
AND COLUMN1 NOT LIKE '%THIS%'
ORDER BY ( CASE WHEN State = 'NULL' THEN 0
ELSE 1
END );
If I run the SQL in Fig. 1 below, it may return something like this:
Select fname, lname from name_tbl where nam_key = :key
Without using some fancy DBA trace utility, how can I query an Oracle system table to find the value of the bind variable “:key”?
Figure 1. - List the current running sql statement.
select sid, username, sql_text
from v$session,
v$sqltext
where sql_address = address
and sql_hash_value = hash_value
order by sid, piece;
select name, value_string
from v$sql_bind_capture
where sql_id = your_query_id
Upd. or, of course:
select sql_id, value_string
from v$sql_bind_capture
where name = ':key'