I am wondering whether is possible to assign a value to a casted column in SQL depending on real table values.
For Example:
select *, cast(null as number) as value from table1
where if(table1.id > 10 then value = 1) else value = 0
NOTE: I understand the above example is not completely Oracle, but, it is just a demonstration on what I want to accomplish in Oracle. Also, the above example can be done multiple ways due to its simplicity. My goal here is to verify if it is possible to accomplish the example using casted columns (columns not part of table1) and some sort of if/else.
Thanks,
Y_Y
select table1.*, (case when table1.id > 10 then 1 else 0 end) as value
from table1
Related
I am using this code to check for data integrity of nvarchar/string data fields. Taking the sum from the view using code below, and comparing that to similar formula in EXCEL to see if I get the same total. Is there a better way? I am new at this.
--Aggregate Boolean fields e.g. nvarchar.
With table1 AS
(
Select
CASE WHEN (field_name) = 'Y' Then 1
WHEN field_name = 'N' Then 2
When field_name IS NULL THEN 3
ELSE field_name
END AS field_name_count
From mysqlview
)
Select SUM(field_name) AS Count
From table1
;
Or this approach
--Count characters in nvarchar column
Select
SUM(LEN(field_name)) AS Count
From mysqlview
;
I can't comment so I'll add my 2 cents here.
you seems to sum a Nvarchar field - can you update your question with the reasoning for this?
Also - in the first example you have sum on 'field_name' while the column name is 'field_name_count'
Do you try to see how many fields contain text and compare this number to your Excel data?
in that case you can count them easily by doing:
select count(1) from mysqlview where fieldname != '' and not fieldname is null
Hope I helped
I want to create a column which finds count of non empty columns in a postgres table (like given below). Can u give me a head's up or a solution?
You can use GENERATED always as column. Example:
create table test (a VARCHAR (50),
b VARCHAR (50),
c VARCHAR (50),
cnt numeric GENERATED always as (
case when a is null then 0 else 1 end +
case when b is null then 0 else 1 end +
case when c is null then 0 else 1 end
) STORED);
Link: https://www.db-fiddle.com/f/fU5LLuh5gvwkKhhRbeCyh8/0
In Postgres, I would simply do:
select t.*,
((a is not null)::int + (b is not null)::int + (c is not null)::int) as cnt
from t;
If you don't want to hard-code the column names, you can use some JSON magic for this:
select a,b,c,
(select count(*) from jsonb_object_keys(jsonb_strip_nulls(to_jsonb(t)))) as num_not_null
from the_table t
jsonb_strip_nulls(to_jsonb(t)) converts the whole row into a single json value where the column names are the keys. Any null value will be removed. Then the keys are extracted using jsonb_object_keys and the number of keys returned is the number of non-null columns in that row.
Using a CASE expression as shown in EragonBY's answer or the boolean expressions in Gordon's answer will be a lot faster if you don't mind explicitly listing all column names.
Online example
I need to use case when to generate the value range for in function (in DB2).
for example, in below code, I want the columnB in (5,6)
select columnA from tableName where columnB in (
(case
when #variable=1 then '4' // specific number
when #variable=2 then '5' //specific number
when #variable=3 then '7,10' // a value range
end)
)
but tried several times and other similar solutions, never got the expected result
how to do this?
Firstly, In function does not read multiple values inside Case statement. The comma must be after every single value in the range.
Second, you can mention a valid condition in your Question, rather than just 1=1. It's always true so, doesn't make sense.
Example:
1) output of below query gives in (5, 6)
select columnA from tableName where columnB in ((case when #variable=1 then 5 end), 6);
2) this gives only records of columnB = 5, let say the second condition is false.
select columnA from tableName where columnB in ((case when #variable=1 then 5 end), (case when #variable=2 then 6 end));
try Something like this
select columnA from tableName
where columnB in (
select * from table(values 4) tmp(NewCol)
where #variable=1
union all
select * from table(values 5) tmp(NewCol)
where #variable=2
union all
select * from table(values 7, 10) tmp(NewCol)
where #variable=3
)
You cannot have string as value range unless you convert it into rowset. I'm not sure how to do this in DB2, but I have something that should work, since according to documentation, DB2 does have unnest(). There are of course other ways to create rowsets.
SELECT columnA
FROM unnest(array[2,6,8,10], array[7,5,6,28]) --create "temp table" for example purposes
WITH ORDINALITY AS a(columnA, columnB) --alias columns from temp table
WHERE
CASE WHEN true THEN --switch true to some other condition
columnB IN(SELECT * FROM unnest(array[5,6])) --unnest(array[]) will create rowset with 2 rows, each having one column holding integer value
END;
You might need to drop alias from AS a(columnA, columnB) since I'm not sure if it works in DB2 and I have not found live DB2 tester (it is required in PostgreSQL where I tested query).
Sorry if this a duplicate, but i haven't found one. Why can't i use my column alias defined in the SELECT from the ORDER BY when i use CASE?
Consider this simple query:
SELECT NewValue=CASE WHEN Value IS NULL THEN '<Null-Value>' ELSE Value END
FROM dbo.TableA
ORDER BY CASE WHEN NewValue='<Null-Value>' THEN 1 ELSE 0 END
The result is an error:
Invalid column name 'NewValue'
Here's a sql-fiddle. (Replace the ORDER BY NewValue with the CASE WHEN... that´'s commented out)
I know i can use ORDER BY CASE WHEN Value IS NULL THEN 1 ELSE 0 END like here in this case but actually the query is more complex and i want to keep it as readable as possible. Do i have to use a sub-query or CTE instead, if so why is that so?
Update as Mikael Eriksson has commented any expression in combination with an alias is not allowed. So even this (pointless query) fails for the same reason:
SELECT '' As Empty
FROM dbo.TableA
ORDER BY Empty + ''
Result:
Invalid column name 'Empty'.
So an alias is allowed in an ORDER BY and also an expression but not both. Why, is it too difficult to implement? Since i'm mainly a programmer i think of aliases as variables which could simple be used in an expression.
This has to do with how a SQL dbms resolves ambiguous names.
I haven't yet tracked down this behavior in the SQL standards, but it seems to be consistent across platforms. Here's what's happening.
create table test (
col_1 integer,
col_2 integer
);
insert into test (col_1, col_2) values
(1, 3),
(2, 2),
(3, 1);
Alias "col_1" as "col_2", and use the alias in the ORDER BY clause. The dbms resolves "col_2" in the ORDER BY as an alias for "col_1", and sorts by the values in "test"."col_1".
select col_1 as col_2
from test
order by col_2;
col_2
--
1
2
3
Again, alias "col_1" as "col_2", but use an expression in the ORDER BY clause. The dbms resolves "col_2" not as an alias for "col_1", but as the column "test"."col_2". It sorts by the values in "test"."col_2".
select col_1 as col_2
from test
order by (col_2 || '');
col_2
--
3
2
1
So in your case, your query fails because the dbms wants to resolve "NewValue" in the expression as a column name in a base table. But it's not; it's a column alias.
PostgreSQL
This behavior is documented in PostgreSQL in the section Sorting Rows. Their stated rationale is to reduce ambiguity.
Note that an output column name has to stand alone, that is, it cannot be used in an expression — for example, this is not correct:
SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- wrong
This restriction is made to reduce ambiguity. There is still ambiguity if an ORDER BY item is a simple name that could match either an output column name or a column from the table expression. The output column is used in such cases. This would only cause confusion if you use AS to rename an output column to match some other table column's name.
Documentation error in SQL Server 2008
A slightly different issue with respect to aliases in the ORDER BY clause.
If column names are aliased in the SELECT list, only the alias name can be used in the ORDER BY clause.
Unless I'm insufficiently caffeinated, that's not true at all. This statement sorts by "test"."col_1" in both SQL Server 2008 and SQL Server 2012.
select col_1 as col_2
from test
order by col_1;
It seems this limitation is related to another limitation in which "column aliases can't be referenced in same SELECT list". For example, this query:
SELECT Col1 AS ColAlias1 FROM T ORDER BY ColAlias1
Can be translated to:
SELECT Col1 AS ColAlias1 FROM T ORDER BY 1
Which is a legal query. But this query:
SELECT Col1 AS ColAlias1 FROM T ORDER BY ColAlias1 + ' '
Should be translated to:
SELECT Col1 AS ColAlias1, ColAlias1 + ' ' FROM T ORDER BY 2
Which will raise the error:
Unknown column 'ColAlias1' in 'field list'
And finally it seems these are because of SQL standard behaviours not an impossibility in implementation.
More info at: Here
Note: The last query can be executed by MS Access without error but will raise the mentioned error with SQL Server.
You could try something like:
select NewValue from (
SELECT (CASE WHEN Value IS NULL THEN '<Null-Value>' ELSE Value END ) as NewValue,
( CASE WHEN NewValue='<Null-Value>' THEN 1 ELSE 0 END) as ValOrder
FROM dbo.TableA
GROUP BY Value
) t
ORDER BY ValOrder
This may be simple, but I am no SQL whiz so I am getting lost. I understand that sql takes your query and executes it in a certain order, which I believe is why this query does not work:
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1
and cast(purchase_order_number as int) >= 7
MOST of the purchar_order_number fields are numeric, but we introduce alphanumeric ones recently. The data I am trying to get is to see if '7' is greater than the highest numeric purchase_order_number.
The Numeric() function filters out the alphanumeric fields fine, but doing the subsequent cast comparison throws this error:
Conversion failed when converting the nvarchar value '124-4356AB' to data type int.
I am not asking what the error means, that is obvious. I am asking if there is a way to accomplish what I want in a single query, preferably in the where clause due to ORM constraints.
does this work for you?
select * from purchaseorders
where (case when IsNumeric(purchase_order_number) = 1
then cast(purchase_order_number as int)
else 0 end) >= 7
You can do a select with a subselect
select * from (
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1) as correct_orders
where cast(purchase_order_number as int) >= 7
try this:
select * from purchaseorders
where try_cast(purchase_order_number as int) >= 7
have to check which column has numeric values only.
Currently, in a table every field is setted with nvarchar(max) Like tableName (field1 nvarchar(max),field2 nvarchar(max),field3 nvarchar(3)) and tableName has 25lac Rows.
But on manually Check Field2 Contain the numeric Values Only... How to Check With t-sql that in the Complete Column (Field2) has numeric Value or not/null value with Longest Length in the Column!