Oracle SQL Group BY via column substr - sql

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

Related

An issue with specifying a column "Percent" in SQL Select query

There is a table with a column name PERCENT. I need to run an ordinary SELECT query:
SELECT *
FROM <my_table>
WHERE PERCENT = 100
However, I get this error message:
Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'PERCENT'
Is there a way to indicate a column so the system accepts it as a column name instead of a function?
PERCENT is a reserved word. Use escape characters:
SELECT *
FROM <my_table>
WHERE [PERCENT] = 100
It is used, for instance, with TOP as in TOP 100 PERCENT.
Enclose the column name in square brackets (i.e. [PERCENT]) or the ANSI/ISO standard double quotes (i.e. "PERCENT"). This will allow you to use reserved T-SQL keywords in identifiers.
I suggest one avoid using reserved keywords as object or column names to avoid this requirement.

Bigquery SELECT * FROM table where column = 'string' not returning any values

When I run the following query in bigqeury I am getting no results.
SELECT COUNT(*) FROM raw.bicc_customers WHERE sub_type = "SUD"
I don't get any results
However, when I run
SELECT COUNT(*) FROM raw.bicc_customers WHERE sub_type LIKE "%SUD%"
I get results. The field that I'm looking for is SUD with no spaces, I don't understand why I need wildcards to find it. What am I missing?
EDIT:
So in the table the column is actually "SUD" - How would you find this without wildcards?
I couldn't add a comment, because I'm too new.
But try doing this query to help you determine what's wrong.
SELECT LENGTH(sub_type ) FROM raw.bicc_customers WHERE sub_type LIKE "%SUD%"
If you see that all the length values are greater than 3, that means you have some white space characters around it.
You can also do this to check:
SELECT LENGTH(sub_type ) FROM raw.bicc_customers WHERE LTRIM(RTRIM(sub_type)) = "SUD"
So in the table the column is actually "SUD" - How would you find this
without wildcards?
Option 1 - escaping double quotes - see Escaping special characters in strings for more details
SELECT COUNT(*)
FROM raw.bicc_customers
WHERE sub_type = "\"SUD\""
Option 2 - using single quotes
SELECT COUNT(*)
FROM raw.bicc_customers
WHERE sub_type = '"SUD"'

Remove last two characters from each database value

I run the following query:
select * from my_temp_table
And get this output:
PNRP1-109/RT
PNRP1-200-16
PNRP1-209/PG
013555366-IT
How can I alter my query to strip the last two characters from each value?
Use the SUBSTR() function.
SELECT SUBSTR(my_column, 1, LENGTH(my_column) - 2) FROM my_table;
Another way using a regular expression:
select regexp_replace('PNRP1-109/RT', '^(.*).{2}$', '\1') from dual;
This replaces your string with group 1 from the regular expression, where group 1 (inside of the parens) includes the set of characters after the beginning of the line, not including the 2 characters just before the end of the line.
While not as simple for your example, arguably more powerful.

sqlite: alias column name can't contains a dot "."

(sorry for my poor english)
If you try this select operation over a sqlite database:
SELECT column AS 'alias 1' FROM table;
You get the expected column name:
alias 1
--------
result 1
result 2
but if your alias contains a dot "." ... you get a wrong column name:
SELECT column AS 'alias.1' FROM table;
1
--------
result 1
result 2
(all behind the dot is ommited in the column name)
Wow...
It's weird...
anyone can help me?
thank you very much
UPDATE:
maybe it's just a bug in SQLiteStudio (the software where I'm testing my queries) and in QT (they both doesn't expect dots in alias names but sqlite does)
Enclose your alias in double quotes.
SELECT 'test' AS "testing.this"
Output:
| testing.this |
test
Updated:
Double quotes are used to enclose identifiers in SQL, not single quotes. Single quotes are only for strings. In this case you are trying to ensure that "testing.this" is used as is and not confused as testing.this (testing table this column).
http://www.sqlite.org/faq.html#q24
Use backticks
SELECT column AS `alias.1` FROM table;
Or double quotes (ANSI standard) per the other answer
SELECT column AS "alias.1" FROM table;
Both verified in SQLite Manager for FireFox
Definitely working properly:
C:\Windows>sqlite3.exe
SQLite version 3.7.8 2011-09-19 14:49:19
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .mode column
sqlite> .headers on
sqlite> SELECT 'hello' AS 'alias.1';
alias.1
----------
hello
sqlite>
If you're using the SQLite 3 then the following query works just fine with various types used for the Alias column names.
See the result below the query:
select '1' as 'my.Col1', '2' as "my.Col2", '3' as [my.Col3], '4' as [my Col4] , '5' as 'my Col5'
I've found a "fix"...
SELECT column AS '.alias.1' FROM
table;
alias.1
--------
result 1
result 2
just another dot in the begining...
of course I don't like this solution...
any other idea??
Please try below, it works on Hive
select 1 as `xxx.namewith.dot`
xxx. means any word you want to input with dot notation on latest
namewith.dot means any alias name with dot notation on it

Oracle: a query, which counts occurrences of all non alphanumeric characters in a string

What would be the best way to count occurrences of all non alphanumeric characters that appear in a string in an Oracle database column.
When attempting to find a solution I realised I had a query that was unrelated to the problem, but I noticed I could modify it in the hope to solve this problem. I came up with this:
SELECT COUNT (*), SUBSTR(TITLE, REGEXP_INSTR(UPPER(TITLE), '[^A-Z,^0-9]'), 1)
FROM TABLE_NAME
WHERE REGEXP_LIKE(UPPER(TITLE), '[^A-Z,^0-9]')
GROUP BY SUBSTR(TITLE, REGEXP_INSTR(UPPER(TITLE), '[^A-Z,^0-9]'), 1)
ORDER BY COUNT(*) DESC;
This works to find the FIRST non alphanumeric character, but I would like to count the occurrences throughout the entire string, not just the first occurrence. E. g. currently my query analysing "a (string)" would find one open parenthesis, but I need it to find one open parenthesis and one closed parenthesis.
There is an obscure Oracle TRANSLATE function that will let you do that instead of regexp:
select a.*,
length(translate(lower(title),'.0123456789abcdefghijklmnopqrstuvwxyz','.'))
from table_name a
Try this:
SELECT a.*, LENGTH(REGEXP_REPLACE(TITLE, '[^a-zA-Z0-9]'), '')
FROM TABLE_NAME a
The best option, as you discovered is to use a PL/SQL procedure. I don't think there's any way to create a regex expression that will return multiple counts like you're expecting (at least, not in Oracle).
One way to get around this is to use a recursive query to examine each character individually, which could be used to return a row for each character found. The following example will work for a single row:
with d as (
select '(1(2)3)' as str_value
from dual)
select char_value, count(*)
from (select substr(str_value,level,1) as char_value
from d
connect by level <= length(str_value))
where regexp_instr(upper(char_value), '[^A-Z,^0-9]'), 1) <> 0
group by char_value;