I have a table in oracle db which has a unique index composed of two columns (id and valid_from). The column valid_from is of type timestamps with time zone.
When I query the SYS.USER_IND_COLUMNS to see which columns my table is using as unique index, I can not see the name of the valid_from column but instead I see smth like SYS_NC00027$.
Is there any possibility that I can display the name valid_from rather than SYS_NC00027$. ?
Apparently Oracle creates a function based index for timestamp with time zone columns.
The definition of them can be found in the view ALL_IND_EXPRESSIONS
Something like this should get you started:
select ic.index_name,
ic.column_name,
ie.column_expression
from all_ind_columns ic
left join all_ind_expressions ie
on ie.index_owner = ic.index_owner
and ie.index_name = ic.index_name
and ie.column_position = ic.column_position
where ic.table_name = 'FOO';
Unfortunately column_expression is a (deprecated) LONG column and cannot easily be used in a coalesce() or nvl() function.
Use the below to verify the col info.
select column_name,virtual_column,hidden_column,data_default from user_tab_cols where table_name='EMP';
Related
I am trying to replace all of the NULL values to 0 in a column of a big table in HIVE.
However, every time I try to implement some code I end up generating a new column to the table. The column I am trying to change/modify still exists and still has the NULL values but the new column that is automatically generated (i.e. _c1) is what I want the column I am trying to modify, to look like.
I tried to run a COALESCE but that also ended up generating a new column. I also tried to implement a CASE WHEN, but the same results ensued.
Select *,
CASE WHEN columnname IS NULL THEN 0
ELSE columnname
END
from tablename;
Also tried
SELECT coalesce(columnname, CAST(0 AS BIGINT)) FROM tablename
I would just like to update the table with the other columns being as is but the column I want to modify still has its original name but instead of NULL values it has 0's that replaced them.
I don't want to generate a new column but modify an existing one.
How should I do that?
Use insert overwrite .. option.
insert overwrite table tablename
select c1,c2,...,coalesce(columnname,0) as columnname
from tablename
Note that you have to specify all the other column names required in select.
How can I use a column value as a column name. I've tried this:
SELECT TableX.(
SELECT OdTable.columnamecell
from OdTable
where 1 =1
AND OdTable.KeyValue = TableX.SomeValue
) as MyValue
,TableX.OtherValue as OtherValue
, TableX.SomeValue
from TableX
WHERE 1 = 1
Or to say it another way: Can I use a table column value as a column name for another query or sub-query?
To clarify: The table: OdTable has a column with values that are the column name in another table.
No, and Yes. You can't do this with "standard" SQL; all table and column names must be known, as literals, when the query is compiled; they can't be provided at runtime. What you want is called "dynamic SQL"; sometimes it is the only solution to a problem, but most of the time it is used when it is not necessary. It has several disadvantages (security risk, performance penalty, difficulty to maintain, ...)
I want to have a column in table which calculates the value depending on the other column in the same table.
For example,
I have "Validity" Table with Columns "DateManufactured", "DateExpires"
The Date Expires column must calculate value suppose adding 30 days for Datemanufactured.
How Can we do this in Visual Studio2010->DataSet Design-> DataTable Column-> Properties->Expression
See relevant Image here
What could be the possible expression for this in terms of SQL Server Expressions?
Please Suggest optimal Solution.
Thanks in advance.
I believe you are looking for DateAdd
SELECT DATEADD(day, 30, '15 Dec 1988')
select dateadd(day,30,getdate())
this will take the current date(getdate())
add 30 days to it.
I would suggest creating a stored procedure to insert your data into your table with parameters of the values that needs to be inserted. you can then do your calculation based on your date parameter. Example:
Create Procedure InsertValidity
(
#City varchar(20),
#Area varchar(20),
...
#DatePosted datetime,
...
#UserID
)
as
declare #DurationFrom datetime
set #DurationFrom = (select DATEADD(dd,30,#DatePosted)
insert into Validity (City, Area, ..., DatePosted, ... UserID)
values(#City, #Area, ..., #DatePosted,...#DurationFrom,...#UserID)
This should solve your problem. Just complete the script by replacing the ... with your other data then execute the stored procedure in your application.
In Oracle I have two tables. Both are populated with data and have a timestamp column.
One table has that column filled with data, the other table doesn't. But I need to get the data from the table that does into the column of the other table based on a match of another column.
Each has 'code' so the timestamp from the one table should only be put in the timestamp of the other table where the codes match.
I've tried cursors etc, but it seems like I'm missing something.
Any suggestions?
It sounds like you want a correlated update. This will update every row of destinationTable with the timestamp_col from sourceTable where there is a match on the code column.
UPDATE destinationTable d
SET timestamp_col = (SELECT s.timestamp_col
FROM sourceTable s
WHERE s.code = d.code )
WHERE EXISTS( SELECT 1
FROM sourceTable s
WHERE s.code = d.code )
Just for completeness, I think I would have done something like this (untested), if the destination has a primary key or unique column:
UPDATE (
SELECT d.primary_key AS pk, d.timestamp_col AS dest_col, MAX(s.timestamp_col) AS src_col
FROM dest d
JOIN src s ON d.code = s.code
GROUP BY pk, dest_col
) j
SET j.dest_col = j.src_col
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.