Oracle select max id from table returns null value - oracle

I have the query:
SELECT MAX(prod_id) FROM products;
It returns the maximum value if there are records. But, if I truncate table and run the same query I am unable to get the max id.

In case you want to query a table's column and suspect that the max function may return null, then you can return 0 in case null is encountered
SELECT NVL(MAX(P.PROD_ID), 0) AS MAX_VAL
FROM PRODUCTS P
This will return at least 0 , if no value is encountered for the column that you mention ()

Yes, by truncating the table you have removed all data in it, with no need for a commit. Therefore there is no data in the table and the max of nothing is nothing.

If you truncate the table, there are no rows left in the table. By definition, Max() returns NULL when run against an empty table.... or did I miss something here?

As Gerald P. Wright commented to an answer, if id is generated by a sequence, you can use it to find the value.
But
SELECT prod_id_seq.currval FROM DUAL
won't work, because currval works only in the session where you fetched a value with currval.
so,
SELECT prod_id_seq.nextval FROM DUAL
can be an workaround for you, but would be a realy, realy BAD solution(if you get the id with this several times you'll get incremented values).

Related

CockroachDB pg_column_size retuning null

I am currently using the pg_column_size to calculate the size of a row in the DB.
something like:
select pg_column_size(col1, col2, col3..... col10) from _table
Problem is when 1+ column value is null the whole function returns null.
Is there anyway to set a default value for each column within the function to avoid getting null?
try
select pg_column_size(<table_name>.*) from <table_name>;
Are you specifically trying to select a subset of columns?
If you do select pg_column_size(table) from table;, it should work.

Oracle - select all where one of the columns satisfies predicate

I have a table with 30+ rows and i want to do a select * however i also want to make sure that no rows containing null values are returned for a certain column. How can i do this without having to list each of the column names in the select?
My current SQL looks like this;
select *
from table
where (select column
from table
where column is not null) is > 20
However this does not work as the nested select returns more than one value.
Any suggestions please?
select * from table where column is not null
maybe?
SELECT *
FROM table
WHERE column > 20
Is that sufficient?

Does cardinality in database return numeric values?

I am re-engineering code written in the SQL, and I got a use of cardinality in an order by clause. So on which basis it is going to order the records?
e.g.
ORDER BY
cardinality(emp_ids),
earliest_due_date
where emp_ids are prepared like this
CAST(
collect(employee.emp_id)
AS
NumberList
) AS emp_ids
It is documented that the return is numeric:
CARDINALITY returns the number of elements in a nested table. The
return type is NUMBER. If the nested table is empty, or is a null
collection, then CARDINALITY returns NULL.
So, your order by will return the emp_ids table with the least number of rows in it first (empty ones as it will return null will come last).

Validate person without value in date column

I have a table with several employees. They have the following columns empid,datecolumn1,is_valid.
Very few employees have a more than one record in the table. If an employee has more than one record in the table I would like to 'invalidate' one of the records on the following condition:
1. If a employee has more than one record in the table then the record with no value in the datecolumn1 is valid (update is_valid to 1) and the record with value in datecolumn1 is not valid (update is_valid to 0).
How do I accomplish this?
As Ben points out, you've stated that if datecolumn1 is NULL you want the is_valid column to be set to both 0 and 1. Assuming you fix that, you may need to adjust this CASE statement depending on which way you decide is correct.
UPDATE employees
SET is_valid = (CASE WHEN datecolumn1 IS NULL
THEN 1
ELSE 0
END)
WHERE empid IN (SELECT e.empid
FROM employees e
GROUP BY emempid
HAVING COUNT(*) > 1)
create a staging table, and fill it by a SELECT on the original table with a GROUP BY employee Id (or whatever your unique identifier is). Create a second staging table and fill it by SELECTING on the original table and excluding all rows that match rows in your grouped table. Now you have a table that contains only those people with multiple rows. From your original table, set is_valid to 0 on all rows that match employee id with the second staging table and also have no datecolumn1 (or perhaps that also have a datecolumn1 - your question as of this writing is a bit unclear.) and is_valid to 1 on the others. Once done with that, delete the staging tables, and you should have what you need.
You could also do this with a single more complicated multiselect call, but I find it helpful to use staging tables when things get complicated.

SQL Server 2008 search for date

I need to search rows entered on a specific date.
However the datatype of column I need to search on is datetime, and the datatype of argument is Date.
I can use the the query like
Select result
from table
where
convert(date, Mycolumn) = #selectedDate
but this would affect the SARGability of the query and will not use indexes created on mycolumn.
I was trying to use the following query:
Select result
from table
where
Mycolumn
BETWEEN #selectedDate AND Dateadd(s, -1, Dateadd(D, 1, #selectedDate))
However this does not work since the #selectedDate is Date type and a second can't be added or removed.
Can someone help me with a working query?
Thanks.
It is my understanding that using:
convert(date, Mycolumn) = #selectedDate
is SARGable. It will use the index on Mycolumn (if one exists). This can easily be confirmed by using the execution plan.
Select result
from table
where
Mycolumn >= #selectedDate
AND Mycolumn < Dateadd(D, 1, #selectedDate)
If you need to do these searches a lot, you could add a computed, persisted column that does the conversion to DATE, put an index on it and then search on that column
ALTER TABLE dbo.YourTable
ADD DateOnly AS CAST(MyColumn AS DATE) PERSISTED
Since it's persisted, it's (re-)calculated only when the MyColumn value changes, e.g. it's not a "hidden" call to a stored function. Since it's persisted, it can also be indexed and used just like any other regular column:
CREATE NONCLUSTERED INDEX IX01_YourTable_DateOnly ON dbo.YourTable(DateOnly)
and then do:
SELECT result FROM dbo.YourTable WHERE DateOnly = #SelectedDate
Since that additional info is stored in the table, you'll be using a bit more storage - so you're doing the classic "space vs. speed" trade-off; you need a bit more space, but you get more speed out of it.

Resources