What is the "DATA" keyword in T-SQL for? - sql

I'm working with a database in T-SQL/SQL Server 2016 at the moment which has some stored procedures containing a keyword I'm not familiar with, namely the "DATA" suffix after a query:
SELECT * FROM dbo.TableName DATA
I'm struggling to find any documentation on what the purpose of this "DATA" keyword is. Could someone shed some light please?

It is not some specific keyword. It is just a table alias. Note that if you changed your select to
SELECT DATA.* FROM dbo.TableName DATA
it will work, as the table now has the "DATA" alias. For the same reason, this:
SELECT dbo.TableName.* FROM dbo.TableName DATA
will throw an error.

This is an alias for the table name, usually it is used if we are inner joining the same table more than one time, or when we need to call the table with a shortcut name.
For example if the table has a key named ID, then:
SELECT DATA.* FROM dbo.TableName DATA
where DATA.ID = "1"
is like
SELECT dbo.TableName.* FROM dbo.TableName
where TableName .ID = "1"

Related

Table name after parenthesis notation

I was going through some old-ish SQL code someone else had written that I couldn't quite understand. I have simplified its structure here, but if anyone can walk me through what exactly is going on, that would be appreciated! You may ignore the specific column operations as they were just examples.
SELECT table.*,
column1 - column2
AS 'col1 - col2',
...
columnn
AS 'coln'
FROM
(SELECT
...
) table
What I don't understand is the final line. I am assuming it is the definition of "table" in the FROM (SELECT ...) part, and the ) table part indicates the name of the defined table.
Thanks in advance!
An inner select needs an alias name
select alias_name.* from
(
select * from some_table ...
) alias_name
The 'table' in that final line is an alias for the subquery.
In T-SQL it is AFAIK mandatory to specify an alias for a subquery if you're selecting from a subquery.
You can name the alias whathever you want. It is perfectly ok to use it like this
select * from
( select * from ... ) as X
(The as keyword is not mandatory, but I always specify the alias-name using 'as').

Create new table from SELECT with MAX condition using SQL Server

I have a book table with few columns and rows like below......
Later i filter pubdate column between 2000/01/01 and 2000/12/01 by grouping pub_id....with following query
select pub_id,max(pubdate) as max_date
from book
group by pub_id
having MAX(pubdate) between '2000/01/01' and '2000/12/01'
Results are below :
Now i want to shift filtered data into new table book1, and i tried following query but it ends in error !!!!
select * into book1
from
(
select pub_id,max(pubdate) as max_date
from book
group by pub_id
having MAX(pubdate) between '2000/01/01' and '2000/12/01'
)
I tried following thing and it is working
insert into existing_table
(
select pub_id,max(pubdate) as max_date
from book
group by pub_id
having MAX(pubdate) between '2000/01/01' and '2000/12/01'
)
But i want to push filtered data dynamically into new table ?
So please correct my mistake in insert into query ......
Thanks in advance !!!!!
Give an alias name
Query
select * into book1
from
(
select pub_id,max(pubdate) as max_date
from book
group by pub_id
having MAX(pubdate) between '2000/01/01' and '2000/12/01'
) x
Alias can be used to replace a column name or a table name.
In your case, table alias is needed because sql engine deal with set based logic. If you didn't put a table alias for your defined select statement, the sql engine will not know from which set it should be refer to , even your select statement is valid.
Simply put an alias name will let the sql engine to identify which table (act like a unique ID) to refer.
For instance the simple statement, "select * from TableName", the TableName works like a table alias or an Identity to refer to.
(1) It will not work if you just put "Select * from (Select * from TableName)"
(2) It will work if you put "Select * from (Select * from TableName) x".
Hopefully this explain your doubts.

SQL statement for a join in dB2

The following is my sql statement for a join in dB2.
select name, address, bloodgroup
from user_tb, health_tb
where user_tb.id = health_tb.id;
I am getting the following error:
"health_tb.id" is not valid in the context where it is used..
SQLCODE=-206, SQLSTATE=42703, DRIVER=4.12.79
I understand that one reason why I could be getting this error is because id may not exist in health_tb, but that is not the case. I hope someone can advise. Thank you.
First, you should learn to use modern join syntax, although this has nothing to do with your problem:
select name, address, bloodgroup
from user_tb join
health_tb
on user_tb.id = health_tb.id;
A simple search on Google pointed me to the documentation for this error. One of the first things it mentions is:
Possible reasons for this error include:
The specified column is not a column of any of the source or target
tables or views of the statement.
In a SELECT or DELETE statement, the specified column is not a column of any of the tables or views that are identified in a FROM
clause in the statement.
A column list of an SQL data change statement specified the name of a column of the target table or view of the statement.
I suspect that the id column is really called something like user_id. The working query might look like:
select name, address, bloodgroup
from user_tb join
health_tb
on user_tb.id = health_tb.user_id;
1) check if the id column in both tables have the same data type
2) check if there is any trailing space in the column name
select '<' || column_name || '>' from user_tab_columns
where tbname = 'health_tb'
If the id columns are defined as different types, that could be a problem.

PL/SQL error with transposing string to rows

I am trying to spilt a string in my table into separate rows and then looking up those values in another table to see which values doesn't exists. This is the code I am using:
SELECT NAME, desc, LABEL, trim(x.column_value.extract('e/text()')) AS ID
from table1 T1, table (xmlsequence(xmltype('<e><e>' || replace(str_work,' ','</e><e>')||
'</e></e>').extract('e/e'))) x
where
NOT EXISTS (SELECT *
FROM
tabl2 T2
WHERE
T1.ID = x.ID) AND t1.str_work IS NOT NULL);
The code is giving an error:
ORA-00904: "X"."ID": invalid identifier
I am not able to figure out what the issue is. I would appreciate all your help and suggestions.
Thank you.
From the documentation (emphasis added):
You can use a column alias, c_alias, to label the immediately
preceding expression in the select list so that the column is
displayed with a new heading. The alias effectively renames the select
list item for the duration of the query. The alias can be used in the
ORDER BY clause, but not other clauses in the query.
So you can't refer to the ID alias in the subquery. That alias isn't coming from the inline view you've labelled as x anyway, though. You could solve both issues, I think, by repeating the trim in the subquery:
NOT EXISTS (SELECT *
FROM
tabl2 T2
WHERE
T1.ID = trim(x.column_value.extract('e/text()')))
AND t1.str_work IS NOT NULL);
But is that supposed to be referring to T2.ID - otherwise there is no correlation?
Alternatively you could introduce another inline view to avoid the repetition, but it's probably adding complexity for not much gain here.

sql select into subquery

I'm doing a data conversion between systems and have prepared a select statement that identifies the necessary rows to pull from table1 and joins to table2 to display a pair of supporting columns. This select statement also places blank columns into the result in order to format the result for the upload to the destination system.
Beyond this query, I will also need to update some column values which I'd like to do in a separate statement operation in a new table. Therefore, I'm interested in running the above select statement as a subquery inside a SELECT INTO that will essentially plop the results into a staging table.
SELECT
dbo_tblPatCountryApplication.AppId, '',
dbo_tblPatCountryApplication.InvId,
'Add', dbo_tblpatinvention.disclosurestatus, ...
FROM
dbo_tblPatInvention
INNER JOIN
dbo_tblPatCountryApplication ON dbo_tblPatInvention.InvId = dbo_tblPatCountryApplication.InvId
ORDER BY
dbo_tblpatcountryapplication.invid;
I'd like to execute the above statement so that the results are dumped into a new table. Can anyone please advise how to embed the statement into a subquery that will play nicely with a SELECT INTO?
You can simply add an INTO clause to your existing query to create a new table filled with the results of the query:
SELECT ...
INTO MyNewStagingTable -- Creates a new table with the results of this query
FROM MyOtherTable
JOIN ...
However, you will have to make sure each column has a name, as in:
SELECT dbo_tblPatCountryApplication.AppId, -- Cool, already has a name
'' AS Column2, -- Given a name to create that new table with select...into
...
INTO MyNewStagingTable
FROM dbo_tblPatInvention INNER JOIN ...
Also, you might like to use aliases for your tables, too, to make code a little more readable;
SELECT a.AppId,
'' AS Column2,
...
INTO MyNewStagingTable
FROM dbo_tblPatInvention AS i
INNER JOIN dbo_tblPatCountryApplication AS a ON i.InvId = a.InvId
ORDER BY a.InvId
One last note is that it looks odd to have named your tables dbo_tblXXX as dbo is normally the schema name and is separated from the table name with dot notation, e.g. dbo.tblXXX. I'm assuming that you already have a fully working select query before adding the into clause. Some also consider using Hungarian notation in your database (tblName) to be a type of anti-pattern to avoid.
If the staging table doesn't exist and you want to create it on insert then try the following:
SELECT dbo_tblPatCountryApplication.AppId,'', dbo_tblPatCountryApplication.InvId,
'Add', dbo_tblpatinvention.disclosurestatus .......
INTO StagingTable
FROM dbo_tblPatInvention
INNER JOIN dbo_tblPatCountryApplication
ON dbo_tblPatInvention.InvId = dbo_tblPatCountryApplication.InvId;
If you want to insert them in a specific order then use try using a sub-query in the from clause:
SELECT *
INTO StagingTable
FROM
(
SELECT dbo_tblPatCountryApplication.AppId, '', dbo_tblPatCountryApplication.InvId,
'Add', dbo_tblpatinvention.disclosurestatus .......
FROM dbo_tblPatInvention
INNER JOIN dbo_tblPatCountryApplication ON
dbo_tblPatInvention.InvId = dbo_tblPatCountryApplication.InvId
order by dbo_tblpatcountryapplication.invid
) a;
Try
INSERT INTO stagingtable (AppId, ...)
SELECT ... --your select goes here