I have a table mytable and mydate is a column in it.
However, since the SELECT clause is dynamic, I need to pre-adjust the column with addMinutes.
So, the column is added to the variable with the function such that in the event the column turns up in SELECT the variable is taken over than the actual value in the table.
SELECT mydate FROM "mytable"
original value of mydate is returned
WITH addMinutes(mydate,300) AS mydate SELECT mydate FROM "mytable"
original value of mydate is returned, expected to return variable value
The exact opposite happens; Even if the variable is mentioned (same name as the column), the actual column value overrides the WITH clause.
Do we have a workaround to use WITH clause variables with the same name as the columns in the table?
SELECT
* REPLACE addMinutes(mydate, 300) AS mydate, mytable.mydate
FROM mytable
I'm not aware of any workaround. The real question is: Why do you need the WITH clause to use the same variable name?
Everything works as expected if you use a different name:
WITH
addMinutes(mydate, 300) AS mynewdate
SELECT
mynewdate,
mydate
FROM mytable;
Related
I am using Oracle and trying to create a view in which I will replace one date value with another date value. I am trying to use case when statement, however, I need to use the same column name as an alias and I get the error that I have duplicate column names. Do you know how to fix it or propose the alternative for replacing date value in a column and creating view? I need to keep the original table unchanged.
Code:
create view name_of_view as
select t.*,
(case when birth_date = to_date('4.12.2015', 'DD.MM.YYYY')
then to_date('4.12.1950', 'DD.MM.YYYY')
else birth_date end) as birth_date
from table t;
As #Lukasz Szozda has suggested in the comments, when you try t.* it will retrieve all columns from your table, including birth_date.
So when you add another birth_date as part of your case when, you receive the duplicate column name error.
What you need to do is:
You either change the case when column name to something like: birth_date_new or whatever then you will have both of the columns.
You retrieve all columns by their names and when retrieving birth_date you apply case when.
I have a query in a validation stored procedure. It goes something like this:
SELECT *
FROM Table1
WHERE batchID IN (SELECT id FROM #tempIds)
AND CAST(field1 AS DATE) > CAST(field2 AS DATE)
Both field1 and field2 have valid dates, i.e. doing IdDate on field1/2 returns 1.
The #tempIds table only has one column ID and contains only one row.
When I run the above query, I get this error:
Unable to convert varchar to date
But instead of selecting batch ids from temp table if I put hard-coded ID from the same temp table it works.
Any ideas what could be the issue?
The problem is that you are using varchar to store date (or datetime) values.
Choosing the correct data type for your columns would save you from a lot of problems, this one included. For detailed information, read Aaron Bertrand's Bad habits to kick : choosing the wrong data type.
Now, to address our conversation in the comments - SQL Server does not guarantee the order on which the conditions in the where clause are evaluated. This means that even if all the "date" strings in both your columns are convertible to date values for the specific batchID, you only need one wrong value in one of the columns to raise the "Unable to convert varchar to date" error.
This also means that even if you where to write your query the way Larry B suggested in his answer (now deleted - so for the sake of future readers - this was his suggestion:)
SELECT *
FROM Table1
WHERE batchID IN (SELECT id FROM #tempIds)
AND ISDATE(field1) = 1
AND ISDATE(field2) = 1
AND CAST(field1 AS DATE) > CAST(field2 AS DATE)
There is no guarantee that the last condition (cast(field1 as date) > cast(field2 as date)) will be evaluated after the isdate(field1)=1 condition.
The correct thing to do is to fix the problem - change the data types of the columns to the correct data type.
Assuming that can't be done (if you have no control over the structure of the database, for instance) - you can do a couple of things:
Find all the places where the values in field1 and in field2 can't be converted to dates and fix them. Consider adding a check constraint to validate that the values of these columns can be converted to date (assuming you can).
Separate your query into 2 parts:
;With cte as
(
SELECT *
FROM Table1
WHERE batchID IN (SELECT id FROM #tempIds)
AND ISDATE(field1) = 1
AND ISDATE(field2) = 1
)
SELECT *
FROM cte
WHERE CAST(field1 AS DATE) > CAST(field2 AS DATE)
This will eliminate the error, since you are only casting values where the ISDATE function already returned 1, but might not return some rows you want back, if the value if either field1 or field2 is wrong in these rows.
Normally I would write a statement like:
SELECT * FROM my_table;
But I have two columns, (both of date type), called 'created' and 'edited'. If I do select *, then the date in each of these columns will appear as:
2017-11-04T18:30:00.000Z
I would rather the date appear in DD/MON/YYYY.
To do that, I currently modify my SQL statement to:
SELECT column_name1,column_name2,column_name3,to_char(created, 'DD-MON-YYYY') as created,column_name4.... FROM my_table;
The problem is that although I can format the date, I have the problem of having to specify each column name in the statement. Is there some way I can select all the columns (but rename one or more columns using the method above), without having to specify each column name ?
You can try something like this:
select to_char(t.created,'DD-MON-YYYY') as created,to_char(t.edited,'DD-MON-YYYY') as edited, t.* from my_table t;
I want to create a function in sql server that take as input an id range and delete all the object in that range (included the start and the end).
Let's have for example:
delete_objects_with_id(id_start,id_end)
It will delete all the objects with the id in the range id_start and id_end.
The problem is that the id are of this form: id_start=2017-0001 id_end=2017-0050 is there a sql server function that iterate on a list given a range?
first_issue content id
2011-01-01 test 2011-0001
2012-10-01 test 2012-0001
2012-11-01 test 2012-0002
2012-11-01 test 2012-0003
No, there's no builtin SQL Server function that will iterate on a list given a range.
If the id values are always nine characters, in the format four numeric digits, a dash and four more digits, then a comparison to character strings would get you the id values.
That is, you could write a query (SQL SELECT statement) to return the id values in that range,
SELECT t.id
FROM myobjects t
WHERE t.id >= '2017-0001'
AND t.id <= '2017-0050'
ORDER BY t.id
and with that query, you could define a cursor loop, and loop through (iterate) through those id values returned.
If the id values aren't in a canonical format, then the range operation isn't necessarily going to work. You'd need a mechanism to convert the id values into values that are canonical, so you can do a range.
But I'm not getting why you would need (or want) to iterate, if by "objects" you are referring to "rows" in a table. If you can write a SELECT statement that returns those rows, you could write a DELETE statement using the same predicates, and delete the rows in one fell swoop.
DELETE
FROM myobjects
WHERE id >= '2017-0001'
AND id <= '2017-0050'
It's not at all clear what you are attempting to achieve, why you would need to "iterate". But a cursor loop is one way to do that.
Again, to answer the question you asked: No. There is no "sql server function that iterate on a list given a range"
There is a simple workaround, Just remove - character and cast id as BIGINT
(This will work assuming that the first part of the id is year value and the second part is an id for each year)
DELETE FROM TABLE_1
WHERE CAST(REPLACE(id,'-','') as BIGINT) >= CAST(REPLACE(id_start,'-','') as BIGINT)
AND CAST(REPLACE(id,'-','') as BIGINT) <= CAST(REPLACE(id_end,'-','') as BIGINT)
Or use BETWEEN
DELETE FROM TABLE_1
WHERE CAST(REPLACE(id,'-','') as BIGINT) BETWEEN CAST(REPLACE(id_start,'-','') as BIGINT)
AND CAST(REPLACE(id_end,'-','') as BIGINT)
I understand that AS is used to create an alias. Therefore, it makes sense to have one long name aliased as a shorter one. However, I am seeing a SQL query NULL as ColumnName
What does this imply?
SELECT *, NULL as aColumn
Aliasing can be used in a number of ways, not just to shorten a long column name.
In this case, your example means you're returning a column that always contains NULL, and it's alias/column name is aColumn.
Aliasing can also be used when you're using computed values, such as Column1 + Column2 AS Column3.
When unioning or joining datasets using a 'Null AS [ColumnA] is a quick way to make sure create a complete dataset that can then be updated later and a new column does not need to be created in any of the source tables.
In the statement result we have a column that has all NULL values. We can refer to that column using alias.
In your case the query selects all records from table, and each result record has additional column containing only NULL values. If we want to refer to this result set and to additional column in other place in the future, we should use alias.
It means that "aColumn" has only Null values. This column could be updated with actual values later but it's an empty one when selected.
---I'm not sure if you know about SSIS, but this mechanism is useful with SSIS to add variable value to the "empty" column.
When using SELECT you can pass a value to the column directly.
So something like :
SELECT ID, Name, 'None' AS Hobbies, 0 AS NumberOfPets, NULL AS Picture, '' AS Adress
Is valid.
It can be used to format nicely a query output when using UNION/UNION ALL.
Query result can have a new column that has all NULL values. In SQL Server we can do it like this
SELECT *, CAST(NULL AS <data-type>) AS as aColumn
e.g.
SELECT *, CAST(NULL AS BIGINT) AS as aColumn
How about without using the the as
SELECT ID
, Name
, 'None' AS Hobbies
, 0 AS NumberOfPets
, NULL Picture
Usually adding NULL as [Column] name at the end of a select all is used when inserting into another table a calculated column based on the table you have just selected.
UPDATE #TempTable SET aColumn = Column1 + Column2 WHERE ...
Then exporting or saving the results to another table.