Can you rename a table using the keyword 'AS' and a select statement? - sql

This is probably a stupid question to most of you but I was wondering whether you can rename a column using the 'AS' keyword and a select statement?
Here is my SQL:
Select Main.EmpId
, Associate_List.costCenter, Assignments.Area
, Main.Assignments_1 AS (
Select Assignment_Name
from Assignments
where Assignment_Number = 1
and Assignments.Area = '#Someparemeter'
)
from associate_list
, main
, APU_CC
, Assignments
where Main.Empid = Associate_List.Empid
and substring(Associate_List.CostCenter,1,4) = APU_CC.CostCentre
The only part of SQL I'm wondering about is:
Main.Assignments_1 AS (
Select Assignment_Name
from Assignments
where Assignment_Number = 1
and Assignments.Area = '#Someparemeter'
)
Is this possible or am I talking jibberish or is this just a stupid thing to do?
Many Thanks

The part after as is not a value but a variable name; the SQL database will use it to reference the value of the result set so you can compare/sort/filter them. Therefore this is not possible.
If you must do this, you must read the documentation of your database how to build dynamic queries. But I suggest against it because it will cause strange errors that will be very hard to debug.

I'm not quite sure what you are driving at.
If there is a column in the Main table called Assignments_1, you can rename it in your query (to give a different header at the top of the output or for some other reason) like this...
SELECT MAIN.ASSIGNMENT_1 AS MY_NEW_NAME
FROM etc.
If you want a derived table in your query you name it like this...
SELECT MAIN.ASSIGNMENT_1,
SELECT *
FROM (SELECT THIS, THAT, THE_OTHER
FROM SOME_TABLE) AS DERIVED_TABLE
FROM etc.
If you didn't want either of those things, please clarify and we'll try to help.

In SQL Server, you can assign an alias to a column with AS like so:
...
ColumnName AS ColumnAlias,
...
And you can do it for a "sub-select" like you have in your example. (I wouldn't write the query quite like that--I'd run the subquery first and then plop the result into the second query like so:
DECLARE #Assignment_Name varca(100) -- or however long
SELECT #Assignment_Name = Assignment_Name
from Assignments
where Assignment_Number = 1
and Assignments.Area = #Someparemeter
SELECT
...
#Assignment_Name = Assignment_Name,
...

But you can do this:
Select m.EmpId, l.costCenter,
(Select Area From Assignments a
Where Assignment_Number = 1
And Area = '#Someparemeter') As Area,
(Select Assignment_Name From Assignments a
Where Assignment_Number = 1
And Area = '#Someparemeter') As Assignments_1
From associate_list l
Join main m On m.Empid = l.Empid
Join APU_CC c On c.CostCentre = substring(l.CostCenter,1,4)
or this:
Select m.EmpId, l.costCenter, Asgn.Area,
Asgn.Assignment_Name as Assignments_1
From associate_list l
Join main m On m.Empid = l.Empid
Join APU_CC c On c.CostCentre = substring(l.CostCenter,1,4)
Cross Join (Select Assignment_Name From Assignments a
Where Assignment_Number = 1
And Area = '#Someparemeter') as Asgn

Related

Join SQL Server Showing Duplicate Row

I want to ask something about joining query. I have a query like this:
SELECT b.compilecodingid,
a.subjobfamily,
b.position,
b.nocoding,
( CASE
WHEN (SELECT Count(0)
FROM trlspbia
WHERE learningsystemid = a.learningsystemid
AND compilecodingid = b.compilecodingid
AND moduleid = '2018081616230361362303614'
AND learningroadmap = 'Basic') > 0 THEN 1
ELSE 0
END ) AS CountPickPBIA
FROM trlsplanning a,
trcompilecodingheader b
WHERE a.learningsystemid = b.learningsystemid
AND a.position = b.position
AND a.learningsystemid = '2018081513283162000000001'
order by CountPickPBIA desc
I know it's because Column Position on Table TrLsPlanning has more than 1 data,
Anyone can help me to find the solution?
Thank you.
The simplest solution is probably select distinct:
SELECT cch.compilecodingid, p.subjobfamily, cch.position, cch.nocoding,
(CASE WHEN EXISTS (SELECT 1
FROM trlspbia s
WHERE s.learningsystemid = p.learningsystemid AND
s.compilecodingid = ccb.compilecodingid AND
s.moduleid = '2018081616230361362303614' AND
s.learningroadmap = 'Basic'
)
THEN 1
ELSE 0
END) AS CountPickPBIA
FROM trlsplanning p JOIN
trcompilecodingheader cch
ON p.learningsystemid = cch.learningsystemid AND
p.position = cch.position
WHERE p.learningsystemid = '2018081513283162000000001'
ORDER BY CountPickPBIA DESC;
SELECT DISTINCT incurs its own overhead. But without more information about the structure and contents of the table, this is the simplest solution.
Note other changes in the query:
Table aliases are abbreviations for table names, rather than being arbitrary letters.
The JOIN syntax is fixed, to use modern, proper, and standard JOIN/ON.
All columns are qualified with the table alias, particularly those in the correlated subqueries.
The subquery uses EXISTS rather than COUNT(*). This is both more efficient and it probably better expresses the logic you want.

Update statement in SQL

I am writing an Update trigger and am struggling with the Update statement:
The statement is as below:
UPDATE ARGUS_APP.CMN_REG_REPORTS CARR
SET CARR.DATE_SUBMITTED =
(
SELECT To_Date(M.ACKNOWLEDGMENTHEADER.MESSAGEDATE,'YYYYMMDDHH24MISS') Messagedate
FROM esm_owner.MESSAGES M
WHERE M.ACKNOWLEDGMENTHEADER.MESSAGESENDERIDENTIFIER='PMDA'
)
WHERE CARR.DATE_SUBMITTED =
(
SELECT CARR.DATE_SUBMITTED
FROM esm_owner.safetyreport sr,esm_owner.MESSAGES M,ARGUS_APP.CMN_REG_REPORTS CARR
WHERE sr.report_id=CARR.esm_report_id
AND M.msg_id = sr.msg_id
AND M.ACKNOWLEDGMENTHEADER.MESSAGESENDERIDENTIFIER='PMDA'
)
I get ORA:01427 everytime.
The Table structure is as below:
I have 3 tables
ARGUS_APP.CMN_REG_REPORTS CARR .............having the columns DATE_SUBMITTED(which I want to update) and esm_report_id which joins with the report_id of safety report
ESM_OWNER.SAFETYREPORT SR............having the columns report_id and MSG_ID(joined with the msg_id of the MESSAGES table)
MESSAGES M ..........having the columns MSG_ID and ACKNOWLEDGMENTHEADER.MESSAGESENDERIDENTIFIER
Please help me resolve this.
I'm going to take a wild stab and guess that this is what you are after. They key feature is correlating the subselects with the update (the carr in the subselects refer to the table in the outer statement).
Update
argus_app.cmn_reg_reports carr
set
carr.date_submitted = (
Select
To_Date(m.AcknowledgmentHeader.MessageDate, 'YYYYMMDDHH24MISS') Messagedate
from
esm_owner.Messages m
inner join
esm_owner.SafetyReport sr
on m.msg_id = sr.msg_id
where
carr.esm_report_id = sr.report_id And
m.AcknowledgmentHeader.MessageSenderIdentifier = 'PMDA'
)
Where
Exists (
Select
'x'
From
esm_owner.Messages m
Inner Join
esm_owner.SafetyReport sr
on m.msg_id = sr.msg_id
Where
carr.esm_report_id = sr.report_id and
m.AcknowledgmentHeader.MessageSenderIdentifier = 'PMDA'
)
Here's an example showing the basic principle works:
Example Fiddle
It looks like one of your subqueries is probably returning more than one row of data. You could perhaps check this by running each on its own.
If you want the update to apply to them all, change the
... = (SELECT...
to
... IN (SELECT ...

Providing Language FallBack In A SQL Select Statement

I have a table that represents an Object. It has many columns but also fields that require language support.
For simplicity let's say I have 3 tables:
MainObjectTable
LanguageDependantField1
LanguageDependantField2.
MainObjectTable has a PK int called ID, and both LanguageDependantTables have a foreign key link back to the MainObjectTable along with a language code and the date they were added.
I've created a stored procedure that accepts the MainObjectTable ID and a Language. It will return a single row containing the most recent items from the language tables. The select statement looks like
SELECT
MainObjectTable.VariousColumns,
LanguageDependantField1.Description,
LanguageDependantField2.SomeOtherText
FROM
MainObjectTable
OUTER APPLY
(SELECT TOP 1 LanguageDependantField1.Description
FROM LanguageDependantField1
WHERE LanguageDependantField1.MainObjectTable_ID = MainObjectTable.ID
AND LanguageDependantField1.Language_ID = #language
ORDER BY
LanguageDependantField1.[Default], LanguageDependantField1.CreatedDate DESC) LanguageDependantField1
OUTER APPLY
(SELECT TOP 1 LanguageDependantField2.SomeOtherText
FROM LanguageDependantField2
WHERE LanguageDependantField2.MainObjectTable_ID = MainObjectTable.ID
AND LanguageDependantField2.Language_ID = #language
ORDER BY
LanguageDependantField2.[Default] DESC, LanguageDependantField2.CreatedDate DESC) LanguageDependantField2
WHERE
MainObjectTable.ID = #MainObjectTableID
What I want to add is the ability to fallback to a default language if a row isn't found in the specified language. Let's say we use "German" as the selected language. Is it possible to return an English row from LanguageDependantField1 if the German does not exist presuming we have #fallbackLanguageID
Also am I right to use OUTER APPLY in this scenario or should I be using JOIN?
Many thanks for your help.
Try this:
SELECT MainObjectTable.VariousColumns,
COALESCE(PrefLang.Description,Fallback.Description,'Not Found Desc')
as Description,
COALESCE(PrefLang.SomeOtherText,FallBack.SomeOtherText,'Not found')
as SomeOtherText
FROM MainObjectTable
LEFT JOIN
(SELECT TOP 1 pl.Description,pl.SomeOtherText
FROM LanguageDependantField1 pl
WHERE pl.MainObjectTable_ID = MainObjectTable.ID
AND pl.Language_ID = #language
ORDER BY
pl.[Default], pl.CreatedDate DESC)
PrefLang ON 1=1
LEFT JOIN
(SELECT TOP 1 fb.Description,fb.SomeOtherText
FROM LanguageDependantField1 fb
WHERE fb.MainObjectTable_ID = MainObjectTable.ID
AND fb.Language_ID = #fallbackLanguageID
ORDER BY
fb.[Default], fb.CreatedDate DESC)
Fallback ON 1=1
WHERE
MainObjectTable.ID = #MainObjectTableID
Basically, make two queries, one to the preferred language and one to English (Default). Use the LEFT JOIN, so if the first one isn't found, the second query is used...
I don't have your actual tables, so there might be a syntax error in above, but hope it gives you the concept you want to try...
Yes, the use of Outer Apply is correct if you want to correlate the MainObjectTable table rows to the inner queries. You cannot use Joins with references in the derived table to the outer table. If you wanted to use Joins, you would need to include the joining column(s) and in this case pre-filter the results. Here is what that might look like:
With RankedLanguages As
(
Select LDF1.MainObjectTable_ID, LDF1.Language_ID, LDF1.Description, LDF1.SomeOtherText, ...
, Row_Number() Over ( Partition By LDF1.MainObjectTable_ID, LDF1.Language_ID
Order By LDF1.[Default] Desc, LDF1.CreatedDate Desc ) As Rnk
From LanguageDependantField1 As LDF1
Where LDF1.Language_ID In( #languageId, #defaultLanguageId )
)
Select M.VariousColumns
, Coalesce( SpecificLDF.Description, DefaultLDF.Description ) As Description
, Coalesce( SpecificLDF.SomeOtherText, DefaultLDF.SomeOtherText ) As SomeOtherText
, ...
From MainObjectTable As M
Left Join RankedLanguages As SpecificLDF
On SpecificLDF.MainObjectTable_ID = M.ID
And SpecifcLDF.Language_ID = #languageId
And SpecifcLDF.Rnk = 1
Left Join RankedLanguages As DefaultLDF
On DefaultLDF.MainObjectTable_ID = M.ID
And DefaultLDF.Language_ID = #defaultLanguageId
And DefaultLDF.Rnk = 1
Where M.ID = #MainObjectTableID

SQL - GROUPING, ID, NAME

I was wondering what the answer should be for 1c. on this website:
http://sqlzoo.net/6.htm
SELECT company
FROM route WHERE stop=4
GROUP BY name, ID
this obviously isn't working, the ID and name isn't showing up no matter what. What is missing here? Thanks.
SELECT stops.id, stops.name
FROM route
INNER JOIN stops on route.stop = stops.id
WHERE route.num = 4 AND route.company = 'LRT'
You need to join the tables as the data you want to return is in a different table to the one which filters the data.
This works and does not include any unnecessary table joins. A good rule of thumb is to use EXISTS to verify values in a table that you do not need the output for. Otherwise, you would use a JOIN
SELECT stops.id, stops.name
FROM stops
WHERE EXISTS
(
SELECT 1 FROM route
WHERE route.stop = stops.id AND num = '4' AND company = 'LRT'
)
select s.id, s.name
from stops s
inner join route r
on s.id = r.stop
where r.num= 4
AND r.company= 'LRT'
It gives you this error:
sql: Unknown column 'name' in 'group statement'
There is no name in route tabel.
The tables structure are:
stops(id, name)
route(num,company,pos, stop)
So the answer for this quiz is:
SELECT s.id, s.name
FROM route r, stops s
WHERE r.stop= s.id
and r.num = 4 AND r.company = 'LRT'

Variable not getting set by select

I have an issue where a variable is not getting set by a select statement.
The select joins a table variable #contracts (which is used to control a loop) and then joins to the real contract and contract line tables.
my select is:
select top 1
#contract_id = c.contract_id
, #account = ch.account
, #service = cl.service
, #model = cl.model
, #serial = cl.serial
, #contract = ch.contract
from
#contracts c
inner join contractline cl on c.contract_id = cl.contract_id
inner join contractheader ch on cl.contract = ch.contract
where
cl.contract_id = #contract_id
But when I do a select #contract_id say i get a NULL back, as do all my variables.
I have done a simple select * from #contracts c inner join contractline cl on c.contract_id = cl.contract_id inner join contractheader ch on cl.contract = ch.contract and this returns exactly 1 line with the values in all the correct places, no nulls in the selected values.
What have I done wrong?
Looks like your WHERE clause could be stopping the row from returning. You mentioned you've tested the same SELECT without setting variable, but the code you listed doesn't include this WHERE - so its not the same.
Test your SELECT with the WHERE in place, with dummy values (likely NULL) and review. It simply sounds like its not returning a result.
You are setting #contract_id in the select statement but then also using it in the where clause. I would have thought that #contract_id will be null?