T-SQL - Aliasing using "=" versus "as" [closed] - sql

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
This post was edited and submitted for review 5 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
Is there any particular reason (performance or otherwise) to use AS ahead of = when aliasing a column?
My current approach (for readability) is to use this:
select
alias1 = somecolumn
alias2 = anothercolumn
from
tables
etc...
instead of this:
select
somecolumn as alias1
anothercolumn as alias2
from
tables
etc...
Is there a performance or maintainability reason to use one over the other?

‘=’ isn't valid ANSI SQL, so you'll have difficulty should you wish to run your application on a different DBMS.
(It's when ANSI form is used but the optional ‘AS’ is omitted I find the results difficult to read, personally.)

To put in some counterweight, I prefer using =.
If I am the consumer of the query results in some way, I find it more convenient to see what columns I as a consumer can use.
I prefer this
SELECT
[ElementObligationID] = #MaxElementObligationID + eo.ElementObligationID
, [ElementID] = eo.ElementID
, [IsotopeID] = eo.IsotopeID
, [ObligationID] = eo.ObligationID
, [ElementWeight] = eo.ElementWeight * -1
, [FissileWeight] = eo.FissileWeight * -1
, [Items] = eo.Items * -1
, [Comment] = eo.Comment
, [AdditionalComment] = eo.AdditionalComment
, [Aanmaak_userid] = #UserID
, [Aanmaak_tijdstip] = GetDate()
, [Laatste_wijziging_userid] = #UserID
, [Laatste_wijziging_tijdstip] = GetDate()
FROM dbo.KTM_ElementObligation eo
INNER JOIN dbo.KTM_ElementObligationArticle eoa ON
eoa.ElementObligationID = eo.ElementObligationID
over this
SELECT
#MaxElementObligationID + eo.ElementObligationID AS [ElementObligationID]
, eo.ElementID AS [ElementID]
, eo.IsotopeID AS [IsotopeID]
, eo.ObligationID AS [ObligationID]
, eo.ElementWeight * -1 AS [ElementWeight]
, eo.FissileWeight * -1 AS [FissileWeight]
, eo.Items * -1 AS [Items]
, eo.Comment AS [Comment]
, eo.AdditionalComment AS [AdditionalComment]
, #UserID AS [Aanmaak_userid]
, GetDate() AS [Aanmaak_tijdstip]
, #UserID AS [Laatste_wijziging_userid]
, GetDate() AS [Laatste_wijziging_tijdstip]
FROM dbo.KTM_ElementObligation eo
INNER JOIN dbo.KTM_ElementObligationArticle eoa ON
eoa.ElementObligationID = eo.ElementObligationID
just my 2c.

I wouldn't use it simply as it looks far too much like equality operation. 'AS' is clear inasmuch that it's not ambiguous to me.
Its the same as not using upper case in sql, I find it harder to read.

I'm not as lucky as others who have posted here. The code I work with is usually written by someone else and it is rare that there are not CASE statements or other calculations, concatenations or logic that cause a single entry to span over several rows of T_SQL script.
Using a equal sign instead of 'AS' is by far easier to read. With an equal sign you know the alias name you are looking for is in the first position of the row. When 'AS' is used and the T_SQL spans multiple lines, the alias name could literally be anywhere.
It is far, far, far easier to find the 'Items' alias when equals is used than when 'AS' is used.
SELECT
ElementObligationID = #MaxElementObligationID + eo.ElementObligationID
, ElementID = eo.ElementID
, IsotopeID = eo.IsotopeID
, ObligationID = eo.ObligationID
, ElementWeight = eo.ElementWeight * -1
, FissileWeight = eo.FissileWeight * -1
, Items = CASE WHEN eo.Items < 0 THEN eo.Items * -1
WHEN eo.Items > 0 THEN eo.Items
ELSE 0 END
, Comment = eo.Comment
, AdditionalComment = eo.AdditionalComment
, Aanmaak_userid = #UserID
, Aanmaak_tijdstip = GetDate()
, Laatste_wijziging_userid = #UserID
, Laatste_wijziging_tijdstip = GetDate()
FROM dbo.KTM_ElementObligation eo
INNER JOIN dbo.KTM_ElementObligationArticle eoa ON
eoa.ElementObligationID = eo.ElementObligationID
Now imagine having more than 5 times the amount of code that is here and needing to find the 'Items' alias.
SELECT
#MaxElementObligationID + eo.ElementObligationID AS ElementObligationID
, eo.ElementID AS ElementID
, eo.IsotopeID AS IsotopeID
, eo.ObligationID AS ObligationID
, eo.ElementWeight * -1 AS ElementWeight
, eo.FissileWeight * -1 AS FissileWeight
, CASE WHEN eo.Items < 0 THEN eo.Items * -1
WHEN eo.Items > 0 THEN eo.Items
ELSE 0 END AS Items
, eo.Comment AS Comment
, eo.AdditionalComment AS AdditionalComment
, #UserID AS Aanmaak_userid
, GetDate() AS Aanmaak_tijdstip
, #UserID AS Laatste_wijziging_userid
, GetDate() AS Laatste_wijziging_tijdstip
FROM dbo.KTM_ElementObligation eo
INNER JOIN dbo.KTM_ElementObligationArticle eoa ON
eoa.ElementObligationID = eo.ElementObligationID
'AS' vs '=' is not a capricious and arbitrary preference. I am not exaggerating when I say there have been times when it would take several minutes to find the alias name I am looking for because the author of the script I am now in charge of maintaining did not use the equals sign with their alias. I cannot think of a bigger waste of time, money and resources than paying an IT professional to look for alias names in code!! There is a right and wrong answer if you care about maintainability, readability, and efficiency. Your job is to provide business value, not to spend your day looking for Waldo!

"=" is just plain ambiguous.
If you indent to break out each select clause...
select
alias1 = somecolumn,
alias2 = anothercolumn,
result = column1 * column2
from
table
....
select
somecolumn as alias1,
anothercolumn as alias2,
column1 * column2 as result
from
tables
...

= can be confused with assignment and equality; actually, the form I really don't like is when it looks like a string (usually when spaces are involved):
somecolumn as 'alias 1'
or
'alias 1' = somecolumn
I far prefer the alternative notation:
somecolumn as [alias 1]

The postfix alias form (with or without the "AS") is consistent between column and table aliases. Personally, I'd like an option to enforce the use of "AS", and then you wouldn't have the situation:
select
columnA,
columnB
columnC
from
table
producing a result set with two columns instead of the expected 3.
I'd also say that with the prefix "=" form, it can make it more difficult to read if you're mixing obtaining a result set and variable assignment:
select
cA = columnA,
#cB = columnB,
cC = columnC
from
table

The three ways I know of to alias:
TableColumn AS MyAlias
TableColumn MyAlias
MyAlias = TableColumn
Re: 1), I prefer this as it is the most self-documenting code (IMO), and it lets me search for AS if I need to find aliases..
Re: 2), This is my second choice, but without the AS, I am never sure whether this is a cut-and-paste error or not, especially in long, badly-formatted queries.
Re: 3), I don't like this because a) it looks like an assignment, and b) it blends in too much with ON clauses and CASE statements
So, my vote is to use the AS keyword for your aliases.

I prefer using AS since = is used in the where statement, and can be confusing in a long query.

I prefer using neither of those. I just give the name of the column without any keyword in between
SELECT MAX(price_column) maximumprice FROM prices

Column aliases declared by "=" syntax are deprecated in SQL Server 2008 and not supported in the next version. See MSDN article.

While I have a preference for using AS, the really key thing here is to have a corporate standard and to follow it. If more of your people use AS than = then everyone should use it. Coding standards are what makes it easier to maintain code not the particular standard you pick. If everyone uses the same thing, then your eye gets used to picking it out.

I like the
SELECT
column1 = table.column1
,column2 = table.colum2
FROM table
I find AS not as easily noticable compared to a = sign (I can spot = quicker than AS)
Also when one just does SELECT column alias, sometimes it's confusing to know which one is which :)

Since I write SQL for several different relational database management systems, I prefer to use a syntax which works on all of them, which normally means writing ANSI compatible SQL. My normal formatting preference is:
SELECT
S.name AS SchemaName,
O.name AS ObjectName,
C.column_id AS ColumnId,
C.name AS ColumnName
FROM
sys.schemas AS S
INNER JOIN sys.objects AS O ON S.schema_id = O.schema_id
INNER JOIN sys.columns AS C ON O.object_id = C.object_id
ORDER BY
S.name ASC,
O.name ASC,
C.column_id ASC;
As an alternative formatting of the above, the following makes it easier to see the column alias names:
SELECT
S.name
AS SchemaName,
O.name
AS ObjectName,
C.column_id
AS ColumnId,
C.name
AS ColumnName
FROM
sys.schemas AS S
INNER JOIN sys.objects AS O ON S.schema_id = O.schema_id
INNER JOIN sys.columns AS C ON O.object_id = C.object_id
ORDER BY
S.name ASC,
O.name ASC,
C.column_id ASC;

**even i prefer using 'as' instead of '=' . '=' makes confusion in code.
e.g :
column as alias1

You don't have to use either
Drop the AS and use
SELECT originalname alias
FROM
tablename

Related

How to make LIKE behave case-insensitive?

I have an importedParameter which I want to search inside of a column in a SELECT.
But for now it is case-sensitive, how can I make it case-insensitive ?
I've tried multiple things: AND LOWER(columnName) LIKE LOWER(#lv_string) or AND columnName LIKE #tst_string COLLATE utf8_general_ci and some other stuff but got this error:
A Boolean expression is required in positions starting with LOWER(Q.
Sample code:
DATA(tst_string) = '%' && importedParamter && '%'.
IF anotherParameter IS NOT INITIAL.
IF importedParamter IS NOT INITIAL.
SELECT * FROM <table1> as p
INNER JOIN <table2> as q on q~column1 = p~column1
WHERE p~column2 = #anotherParameter
AND q~column2 LIKE #tst_string
INTO CORRESPONDING FIELDS OF TABLE #anotherName
ENDIF.
ENDIF.
I believe Regex is your preferred choice: LIKE_REGEXPR:
SELECT *
FROM <table1> as p
INNER JOIN <table2> as q on q~column1 = p~column1
WHERE p~column2 = #anotherParameter
AND like_regexpr( pcre = '\bparam\b', value = q~column2, CASE_SENSITIVE = 'X' ) = '1'
INTO TABLE DATA(#anotherName).
It has CASE_SENSITIVE predicate which respects (or not) the case.
Though this is available only since ABAP 7.55, so on lower releases you are out of the luck.
This code works fine for me:
SELECT *
FROM adrp
WHERE LOWER( name_first ) LIKE 'phi%'
INTO TABLE #DATA(results).
It finds my personal data entry (as well as those of another "Philipp" and of a "Philip"), even though we are all spelled with a capital P.
LIKE LOWER( 'Phi%' ) does not work, but when you can't control the input, then you can convert it to lower case before the select:
DATA(tst_string) = 'Phi%'.
TRANSLATE tst_string TO LOWER CASE.
SELECT *
FROM adrp
WHERE LOWER( name_first ) LIKE #tst_string
INTO TABLE #DATA(results).
Release: 7.54
I am not sure which release specifically allowed functions like LOWER within the WHERE clause. According to the comments, it should work since 7.51.

Inserting Replace Function into Query

I found this solution which I'm pretty sure will do exactly what I'm trying to accomplish, unfortunately, all my SQL is self-taught and I can't figure out how to integrate the solution into the query I'm working with.
I tried putting everything above the SELECT statement, but I couldn't set the #testString variable to the COND_NOTE.TEXT field, which makes sense, since all of that happens inside the main query select.
Apologies for essentially asking someone to give me a crash course in presumably a pretty basic application of SQL syntax.
SELECT
CASE WHEN DM_IAM_D_I_ROOT.ZZCAP_FACILITY = 'N200' THEN 'MT'
WHEN DM_IAM_D_I_ROOT.ZZCAP_FACILITY = 'N202' THEN 'PI'
WHEN DM_IAM_D_I_ROOT.ZZCAP_FACILITY = 'N204' THEN 'FL'
ELSE 'Err' END AS FAC
,right(DM_IAM_D_I_ROOT.ISSUE_ID,12) AS ISS_ID
--The following line is the one that I want to use the solution from the referenced question in.
,REPLACE(REPLACE(COND_NOTE.TEXT, '"', '"'), 'br/>', '') NOTES
,COND_NOTE.LINE_COUNTER
FROM
DM_IAM_D_I_ROOT
LEFT JOIN
(
SELECT
DM_BOBF_D_TXCROOT.HOST_KEY
,DM_BOBF_D_TXCROOT.MANDT
,DM_BOBF_D_TXCTXT.TEXT_TYPE
,DM_BOBF_D_TXCCON.LINE_COUNTER
,DM_BOBF_D_TXCCON.TEXT
FROM
DM_BOBF_D_TXCROOT
INNER JOIN DM_BOBF_D_TXCTXT
ON DM_BOBF_D_TXCROOT.DB_KEY = DM_BOBF_D_TXCTXT.PARENT_KEY AND DM_BOBF_D_TXCROOT.MANDT = DM_BOBF_D_TXCTXT.MANDT
INNER JOIN DM_BOBF_D_TXCCON
ON DM_BOBF_D_TXCTXT.DB_KEY = DM_BOBF_D_TXCCON.PARENT_KEY AND DM_BOBF_D_TXCTXT.MANDT = DM_BOBF_D_TXCCON.MANDT
WHERE
DM_BOBF_D_TXCROOT.MANDT = '100'
AND DM_BOBF_D_TXCTXT.TEXT_TYPE = 'ZCOND'
) COND_NOTE ON DM_IAM_D_I_ROOT.DB_KEY = COND_NOTE.HOST_KEY AND DM_IAM_D_I_ROOT.MANDT = COND_NOTE.MANDT
WHERE
DM_IAM_D_I_ROOT.ISSUE_TYPE = 'CAP'
AND DM_IAM_D_I_ROOT.MANDT = '100'
AND DM_IAM_D_I_ROOT.LCYCLE_CD NOT IN ('10', '64')
ORDER BY ZZCAP_FACILITY, ISSUE_ID, LINE_COUNTER

How can I make sure results from a CASE Statement are not shown in my query? [duplicate]

I am running into the error stated in the Title when I attempt to use the alias of a decode in my select statement. Here is the code:
SELECT DISTINCT rl.complaint_date,
decode(rl.judgement_date,null,rl.complaint_amt,rl.judgement_amt) as account_amt,
rl.date_served1,
rl.date_served2,
rl.judgement_date,
rl.skip_locate,
rl.case_no,
lcc.bal_range_min,
lcc.bal_range_max,
lcc.cost_range_min,
lcc.cost_range_max,
lcc.court,
lcc.county AS lcc_county,
ah.ACCOUNT,
ah.transaction_code,
ah.transaction_date,
ah.rule_id,
ah.amount,
ah.description,
r.state,
r.zip_code,
z.county AS ah_county,
z.county_2,
z.county_3,
z.county_4
FROM legal_address_skip las,
racctrel r,
ziplist z,
legal_court_cost lcc,
racctlgl rl,
legal_transaction_review ah
WHERE ah.ACCOUNT = rl.ACCOUNT
AND ah.ACCOUNT = las.ACCOUNT(+)
AND ah.ACCOUNT = r.ACCOUNT
AND nvl(lpad(substr(r.zip_code,0,instr(r.zip_code,'-')-1),5,0), substr(r.zip_code,1,5)) = z.zip
AND r.state = lcc.state
AND (REPLACE(lcc.county,' ','') = REPLACE(upper(z.county),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_2),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_3),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_4),' ',''))
AND lcc.transaction_code = ah.transaction_code
AND lcc.transaction_code = 1
AND lcc.end_date IS NULL
AND ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max
AND (account_amt NOT BETWEEN lcc.bal_range_min AND lcc.bal_range_max
OR lcc.bal_range_min - account_amt NOT BETWEEN 0 AND 500)
ORDER BY CASE
WHEN ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 1
WHEN ah.amount BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 2 END, ah.amount;
I've used aliases before in select statements so I'm confused on why I am getting an error for this. Does it work differently in this situation?
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 alias in the where clause, where at the moment you have:
...
AND (account_amt NOT BETWEEN ...
...
The alias isn't valid at that point, so it's looking for a column with that name in one of the tables, and doesn't find one. It's fine in the order by though.
You either need to replace the alias with the repeated decode statement, or possibly use a subquery and then refer to the alias in a where clause in an outer query, but that might end up being less efficient depending on how selective your other conditions are.
Oracle runs the select query in the order below:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
Based on the above, you can see that when you are in the WHERE part, the alias has not yet been created. If you would like to use results from the SELECT part, you can do that by modifying your query like this:
WITH q AS
(
-- Your query without the extra AND
)
SELECT *
FROM q
WHERE --put your check here
This way you will already have the alias available when you reach the WHERE part.
Hope this helps! :)

ORA-00904 invalid identifier on decode alias

I am running into the error stated in the Title when I attempt to use the alias of a decode in my select statement. Here is the code:
SELECT DISTINCT rl.complaint_date,
decode(rl.judgement_date,null,rl.complaint_amt,rl.judgement_amt) as account_amt,
rl.date_served1,
rl.date_served2,
rl.judgement_date,
rl.skip_locate,
rl.case_no,
lcc.bal_range_min,
lcc.bal_range_max,
lcc.cost_range_min,
lcc.cost_range_max,
lcc.court,
lcc.county AS lcc_county,
ah.ACCOUNT,
ah.transaction_code,
ah.transaction_date,
ah.rule_id,
ah.amount,
ah.description,
r.state,
r.zip_code,
z.county AS ah_county,
z.county_2,
z.county_3,
z.county_4
FROM legal_address_skip las,
racctrel r,
ziplist z,
legal_court_cost lcc,
racctlgl rl,
legal_transaction_review ah
WHERE ah.ACCOUNT = rl.ACCOUNT
AND ah.ACCOUNT = las.ACCOUNT(+)
AND ah.ACCOUNT = r.ACCOUNT
AND nvl(lpad(substr(r.zip_code,0,instr(r.zip_code,'-')-1),5,0), substr(r.zip_code,1,5)) = z.zip
AND r.state = lcc.state
AND (REPLACE(lcc.county,' ','') = REPLACE(upper(z.county),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_2),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_3),' ','')
OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_4),' ',''))
AND lcc.transaction_code = ah.transaction_code
AND lcc.transaction_code = 1
AND lcc.end_date IS NULL
AND ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max
AND (account_amt NOT BETWEEN lcc.bal_range_min AND lcc.bal_range_max
OR lcc.bal_range_min - account_amt NOT BETWEEN 0 AND 500)
ORDER BY CASE
WHEN ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 1
WHEN ah.amount BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 2 END, ah.amount;
I've used aliases before in select statements so I'm confused on why I am getting an error for this. Does it work differently in this situation?
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 alias in the where clause, where at the moment you have:
...
AND (account_amt NOT BETWEEN ...
...
The alias isn't valid at that point, so it's looking for a column with that name in one of the tables, and doesn't find one. It's fine in the order by though.
You either need to replace the alias with the repeated decode statement, or possibly use a subquery and then refer to the alias in a where clause in an outer query, but that might end up being less efficient depending on how selective your other conditions are.
Oracle runs the select query in the order below:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
Based on the above, you can see that when you are in the WHERE part, the alias has not yet been created. If you would like to use results from the SELECT part, you can do that by modifying your query like this:
WITH q AS
(
-- Your query without the extra AND
)
SELECT *
FROM q
WHERE --put your check here
This way you will already have the alias available when you reach the WHERE part.
Hope this helps! :)

SQL Server Compact won't allow subselect but inner join with groupby not allowed on text datatype

I have the following sql syntax that I used in my database query (SQL Server)
SELECT Nieuwsbrief.ID
, Nieuwsbrief.Titel
, Nieuwsbrief.Brief
, Nieuwsbrief.NieuwsbriefTypeCode
, (SELECT COUNT(*) AS Expr1
FROM NieuwsbriefCommentaar
WHERE (Nieuwsbrief.ID = NieuwsbriefCommentaar.NieuwsbriefID
AND NieuwsbriefCommentaar.Goedgekeurd = 1)) AS AantalCommentaren
FROM Nieuwsbrief
I'm changing now to sql-server-ce (compact edition) which won't allow me to have subqueries like this. Proposed solution : inner join. But as I only need a count of the subtable 'NieuwsbriefCommentaar', I have to use a 'group by' clause on my base table attributes to avoid doubles in the result set.
However the 'Nieuwbrief.Brief' attribute is of datatype 'text'. Group by clauses are not allowed on 'text' datatype in sql-server-ce. 'Text' datatype is deprecated, but sql-server-ce doesn't support 'nvarchar(max)' yet...
Any idea how to solve this? Thx for your help.
I think that the solution could be easier. I don't know exactly how is your metadata but I think that this code could fit your requirements by simply using LEFT JOIN.
SELECT Nieuwsbrief.ID
, Nieuwsbrief.Titel
, Nieuwsbrief.Brief
, Nieuwsbrief.NieuwsbriefTypeCode
, COUNT(NieuwsbriefCommentaar.NieuwsbriefID) AS AantalCommentaren
FROM Nieuwsbrief
LEFT JOIN NieuwsbriefCommentaar ON (Nieuwsbrief.ID = NieuwsbriefCommentaar.NieuwsbriefID)
WHERE NieuwsbriefCommentaar.Goedgekeurd = 1
Edited: 2ndOption
SELECT N.ID, N.Titel, N.Brief, N.NieuwsbriefTypeCode, G.AantalCommentaren FROM Nieuwsbrief as N LEFT JOIN (SELECT NieuwsbriefID, COUNT(*) AS AantalCommentaren FROM NieuwsbriefCommentaar GROUP BY NieuwsbriefID) AS G ON (N.ID = G.NieuwsbriefID)
Please, let me know if this code works in order to find out another workaround..
regards,