Creating a new attribute in Oracle database from two other attributes - sql

I have a Classes table which is as follows:
Classes(classid, dept_code, course#, sect#, year, semester, limit, class_size, room, TA_B#)
The qeustion is:
Find the classid, dept_code and course# of each undergraduate class (i.e., course# < 500) that was offered in
Spring 2017. For each such class, also list the number of seats available (computed by limit – class_size)
under the header “seats_available”.
I tried this simple approach:
select classes.classid, classes.dept_code, classes.course#,
classes.limit-classes.class_size as'seats_available'
from classes
where limit>class_size and year='2017' and semester='Spring'and course# < 500;
0
But I am getting an error:
ERROR at line 1:
ORA-00923: FROM keyword not found where expected
What am I missing? This error will go if I remove this code of line:classes.limit-classes.class_size as'seats_available'
I am using Oracle database

In the SQL standard identifiers need to be enclosed in double quotes ("). And the Oracle database complies with the standard there.
Single quotes (') are for character constants e.g. as you did in semester='Spring', they can not be used for identifiers like column names, table names or a column alias.
So you need to use:
classes.limit-classes.class_size as "seats_available"
You don't actually need the double quotes though, as your identifier does not contain any invalid characters, so
classes.limit-classes.class_size as seats_available
will work just as well
Unrelated, but: numbers should not be enclosed in single quotes 2017 is a number constant, '2017' is a string constant. So you should use where year = 2017 instead

Related

Oracle SQL Group BY via column substr

SELECT SUBSTR(PRODID,1, 4) AS [PROD4], COUNT(*) AS [NumberOfRows]
FROM [sch].[ProdTable]
GROUP BY SUBSTR(PRODID,1, 4)
We're writing a simple select that would count how many of our products have the same first 4 characters. Our Product IDs are 10 digits/characters.
When running this, however, we get:
SQL Error [936] [42000]: ORA-00936: missing expression
Any idea how to make this work?
The problem is with the square brackets. Oracle does not support that syntax. These identifiers probably do not require quoting anyway, so:
SELECT SUBSTR(PRODID,1, 4) PROD4, COUNT(*) NumberOfRows
FROM sch.ProdTable
GROUP BY SUBSTR(PRODID,1, 4)
If you really need to quote the identifiers (say, if the table name was created as a case-sensitive name, or you do want mixed-case column aliases), then you can use double quotes:
SELECT SUBSTR(PRODID,1, 4) PROD4, COUNT(*) "NumberOfRows"
FROM sch."ProdTable"
GROUP BY SUBSTR(PRODID,1, 4)
Just expanding a bit on #GMB's answer.
[sch].[ProdTable]
In Oracle, that's an incorrect syntax to refer an object. Don't enclose them in [] square brackets:
FROM sch.ProdTable
However, if you actually want to use square brackets for naming your objects(which would be really ugly) you could use quoted identifier. It begins and ends with double quotation marks ". This also makes then case sensitive, and must always be used with double quotation marks whenever you refer to that object.
create table "[t]" as select 'hi' as "[str]" from dual;
select * from "[t]";
[str]
-----
hi
In your SQL, unless your table is created that way, you don't need to that. You could still name your column's alias with square brackets using quoted-identifier:
select 'hi' as "[str]" from dual;
[str]
-----
hi

Pull variables with spaces in between for SQL table using RODBC's sqlQuery

In my SQL Server database table there is one variable with spaces. I am trying to write one query in the RODBC::sqlQuery function but I am not able to use this variable.
I tried to use single quotes but that doesn't work.
I tried to use paste option and create one string for query but even that also did not work.
Following is the query:
p5 <-sqlQuery(con, 'SELECT
a.region,
a.Country,
a.Qtr_ID,
Net_VAT AS Variable_Type,
"Printing" AS [External_Segment],
SUM(a.VR_Value) AS Value
FROM
(SELECT
d.region,
d.Country,
dt.Qtr_ID,
SUM([Actuals YTD] / 1000000) AS VR_Value
FROM ZOOM_DATAMART.dbo.[New_BalSheet_Fact] a
INNER JOIN [dbo].[Buss_Area_Dim_V] b
ON a.Bus_Area_ID = b.Bus_Area_ID
AND b."GBU External Segment Description" = "Printing"
INNER JOIN [dbo].[BSR_Header_GA_Dim_V] c
ON a.BSR_HEADER_GA_KEY = c.BSR_HEADER_GA_KEY
AND c.[Group Account Identifier] IN (1291, 2150, 2151,
2152, 2153, 2154)
INNER JOIN [dbo].[Legal_Company_Dim_V] d
ON a.Legal_Cmp_Key = d.Legal_Cmp_Key
INNER JOIN dbo.Date_Dim dt
ON a.Date_key = dt.Date_key
AND dt.Max_month_Flag = 1
GROUP BY d.region,
dt.Qtr_ID,
d.Country
) a
GROUP BY a.region,
a.Country,
a.Qtr_ID)
The issue is happening with "GBU External Segment Description". I get following error:
chr [1:4] "42S22 207 [Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name 'Printing'." ...
Then I removed double quote from printing but still for "GBU External Segment Description" it doesn't accept and throws following error:
chr [1:3] "42000 102 [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near 'GBU External Segment Description'." ...
The error is not with the fieldname I believe, but with the varchar constant that you are looking for. You should be using single quotes, not double.
This:
a.Bus_Area_ID = b.Bus_Area_ID and b."GBU External Segment Description"= "Printing"
Should be this:
a.Bus_Area_ID = b.Bus_Area_ID and b.[GBU External Segment Description] = 'Printing'
Generally, String values in SQL are not wrapped in double quotes, but single quotes.
Also, in your first line:
p5 <-sqlQuery(con,'SELECT a.region,a.Country,a.Qtr_ID,Net_VAT as Variable_Type,"Printing" as [External_Segment]
Are you trying to output Printing as a constant result from this query? If so, and it is not a field name, then you should also wrap that in ' single quotes, not double. That is likely what is cauing the first error that you are seeing.
So that it becomes:
p5 <-sqlQuery(con,'SELECT a.region,a.Country,a.Qtr_ID,Net_VAT as Variable_Type,'Printing' as [External_Segment]
The previous comment on your question about wrapping fieldnames with [] is correct, you should use [] the square brackets to wrap field names with spaces in them.
This query should work:
p5 <-sqlQuery(con,'SELECT a.region,a.Country,a.Qtr_ID,Net_VAT as Variable_Type,\'Printing\' as [External_Segment]
,SUM(a.VR_Value) as Value
from
(SELECT d.region,d.Country,dt.Qtr_ID
,sum([Actuals YTD]/1000000) as VR_Value
FROM ZOOM_DATAMART.dbo.[New_BalSheet_Fact] a
inner join [dbo].[Buss_Area_Dim_V] b
on
a.Bus_Area_ID = b.Bus_Area_ID and b.[GBU External Segment Description]= \'Printing\'
inner join [dbo].[BSR_Header_GA_Dim_V] c
on
a.BSR_HEADER_GA_KEY= c.BSR_HEADER_GA_KEY and c.[Group Account Identifier] IN (1291,2150,2151,2152,2153,2154)
inner join [dbo].[Legal_Company_Dim_V] d
on a.Legal_Cmp_Key = d.Legal_Cmp_Key
inner join dbo.Date_Dim dt
on a.Date_key = dt.Date_key and dt.Max_month_Flag = 1
group by d.region,
dt.Qtr_ID
,d.Country
) a
Group BY
a.region
,a.Country
,a.Qtr_ID')
Hope this helps.
Overall, your main issue involves confusing and conflating identifiers and literals. As information, in ANSI-SQL (the formal, industry standard of the SQL language that most RDBMS's adhere to including SQL Server, Oracle, Postgres, etc.), single quotes and double quotes are used for different purposes.
Single quotes are used to enclose string literals within char, varchar, text data type columns such as 'Printing'. Your first error message actually points to Printing as the MSSQL engine attempted to search for a column name since you wrapped this value in double quotes.
Double quotes are used for identifiers including column names and table names such as c."Group Account Identifier". Your second error points to the use of qualifying a table alias, c, to a literal value since you wrapped this value in single quotes.
Below are few common uses of this type:
Double quotes explicitly impose case sensitivity. Specifically, when you wrap column names in double quotes, the same characters in camel case, lower case, and upper case render different values and an error will raise if they do not align to the actual case used in table creation (i.e., tbl."ColumnName" <> tbl."COLUMNNAME").
Double quotes help escape special characters (!##$%^&*?) and spaces. Hence, you can use c."Group Account Identifier" to identify the column. However, some RDBMS's have their own escaping symbols for special characters and spaces which are not ANSI standards. For example, SQL Server can use square brackets [...]; MySQL can use backticks `...`; SQLite and MS Access can use both.
Double quotes help escape reserved words of the current RDBMS which for you includes SQL Server's list. However, it is advised not to use such words, special characters, accents, or spaces in column names.
With that said, like any rule there are exceptions. Both types of quotes may be used with string literals for some databases that allow non-ANSI modes. However, this is not advised to do in practice. Unlike most programming languages such as R, Python, PHP, Perl, XSLT that can swap these two types of quotes for string values, SQL at its base core is not one of them.
Therefore, use either quote type accordingly:
'Printing' AS "External_Segment",
...
AND b."GBU External Segment Description" = 'Printing'
...
AND c."Group Account Identifier" IN (1291, 2150, 2151, 2152, 2153, 2154)
Or
'Printing' AS [External_Segment],
...
AND b.[GBU External Segment Description] = 'Printing'
...
AND c.[Group Account Identifier] IN (1291, 2150, 2151, 2152, 2153, 2154)

Strange Invalid identifier error oracle SQL

I have this portion of a Oracle SQL query (lots more above it that doesn't apply to the question)
...
authorw as (
select a.id, (sum(p.w)) "theWeightOfTheAuthor"
from ac a, pc p, authorpublication ap
where a.id = ap.aid and ap.pid = p.id
group by a.id)
select authorCount.id "ID", auth.name "NAME", authorCount.c "TOTAL_NUMBER_OF_PUBS",
athw.theWeightOfTheAuthor "W_SCORE",
(authorCount.C / athw.theWeightOfTheAuthor) "MULT"
from ac authorCount, authorw athw, Author auth
where authorCount.id = athw.id and authorCount.id = auth.id
order by TOTAL_NUMBER_OF_PUBS desc;
where I am receiving an error:
ORA-00904: "ATHW"."THEWEIGHTOFTHEAUTHOR": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 404 Column: 22
Line 404 being the fourth from last line:
(authorCount.C / athw.theWeightOfTheAuthor) "MULT"
NOTE: I can access athw.id just fine, and if I execute up to the authorw creation, the table is printed out correctly with the theWeightOfTheAuthor column as expected. What gives?
Either remove the quotes around "theWeightOfTheAuthor" when you define it, or add quotes when you use it. Quoting the name when defining it makes the name case-sensitive, and because Oracle changes all non-quoted identifiers to UPPER CASE, your reference to the field is actually looking for ATHW.THEWEIGHTOFTHEAUTHOR, which doesn't exist.
A basic rule of Oracle programming is - never quote identifiers. It's a pain. Just don't do it.
Best of luck.
You've specified the column alias in double quotes, with mixed case, as "theWeightOfTheAuthor". When you use double quotes for a column name, Oracle preserves case. When you refer to it without quotes, as athw.theWeightOfTheAuthor, Oracle automatically converts it to upper-case. So the two don't match.
My suggestion is to remove the double quotes from the alias, so it will also be interpreted as upper-case. Alternatively, you could use double quotes for all references to this column, but I don't see any benefit to using mixed case in the column name. (You can still write it as mixed case, for readability, but Oracle will see it as all upper case.)

Escaping a single quote in Oracle regex query

This is really starting to hurt!
I'm attempting to write a query in Oracle developer using a regex condition
My objective is to find all last names that contain charachters not commonly contained in names (non-alpha, spaces, hyphens and single quotes)
i.e.
I need to find
J00ls
McDonald "Macca"
Smithy (Smith)
and NOT find
Smith
Mckenzie-Smith
El Hassan
O'Dowd
My present query is
select * from dm_name
WHERE regexp_like(last_name, '([^A-Za-z -])')
and batch_id = 'ATEST';
which excludes everything expected except the single quote. When it comes to putting the single quote character, the Oracvel SQL Develoepr parser takes it as a literal.
I've tried:
\' -- but got a "missing right parenthesis" error
||chr(39)|| -- but the search returned nothing
'' -- negated the previous character in the matching group e.g. '([^A-Za-z -''])' made names with '-' return.
I'd appreciate anything you could offer.
Just double the single quote to escape your quote.
So
select *
from dm_name
where regexp_like(last_name, '[^A-Za-z ''-]')
and batch_id = 'ATEST'
See also this sqlfiddle. Note, I tried a similar query in SQL developer and that worked as well as the fiddle.
Note also, for this to work the - character has to be the last character in the group as otherwise it tries to find the group SPACE to ' rather than the character -.
The following works:
select *
from dm_name
WHERE regexp_like(last_name, '([^A-Za-z ''-])');
See this SQLFiddle.
Whether SQL Developer will like it or not is something I cannot attest to as I don't have that product installed.
Share and enjoy.

VB6 Syntax Question

Can anyone tell me what this Asterisk(*) is for. ...tblpersonal where empid like '" & idNumber & "*'". What if I replace it with Percent sign(%), what would be the outcome?
The LIKE condition allows you to use wildcards in the where clause of an SQL statement. This allows you to perform pattern matching. The LIKE condition can be used in any valid SQL statement - select, insert, update, or delete.
The patterns that you can choose from are:
% allows you to match any string of any length (including zero length)
_ allows you to match on a single character
Next, let's explain how the _ wildcard works. Remember that the _ is looking for only one character.
For example,
SELECT * FROM suppliers
WHERE supplier_name like 'Sm_th';
This SQL statement would return all suppliers whose name is 5 characters long, where the first two characters is 'Sm' and the last two characters is 'th'. For example, it could return suppliers whose name is 'Smith', 'Smyth', 'Smath', 'Smeth', etc.
Here is another example,
SELECT * FROM suppliers
WHERE account_number like '12317_';
The same way u can use asterisk (*) instead of (%)
I hope its help to you
The Percent (%) sign in SQL says "match any number of characters here". E.g. LIKE '%test' will match abctest, LIKE 'test%' will match testabc
The Asterisk character looks like it'll match a literal *, e.g. matching all empids ending with an asterisk (depending on the version of SQL - see below)
EDIT: See Microsoft Jet wildcards: asterisk or percentage sign? for a more in depth answer on * vs %
This is much more a SQL syntax question than a VB6 one. :-)
You haven't mentioned what database this is talking to (I assume it's talking to a DB). The asterisk is not generally special in SQL (or VB6 strings), and so that query will look for empid being like whatever's in your idNumber followed by an asterisk. Probably not what was intended. If you replace it with a %, you'll be looking for any empid that starts with whatever's in your idNumber variable. If the column is numeric, it will be converted to text before the comparison.
So for instance, if idNumber contains 100, say, and there are empid values in the database with the values 10, 100, 1000, and 10000, the query would match all but the first of those, since "100", "1000", and "10000" are all like "100%".