Expression inside selected column name - sql

Problem: I want to get an average salary of all employees. The query itself is rather simple:
Question: Is it possible to move COUNT(salary) to selected column's title (after AS statement), so the name of the column will be "Average salary of 20 employees"? I've been trying several approaches, but none of them worked. I would really appreciate any help. Thank you in advance.

Screenshot you posted looks like Apex SQL Workshop. I don't know how to do it there, but - if you used SQL*Plus, then you could do something like this (not exactly as you wanted it, though):
SQL> set ver off
SQL> column cnt_emps new_value l_cnt
SQL> select count(*) cnt_emps from emp;
CNT_EMPS
----------
14
SQL> select avg(sal) as "Average salary of &l_cnt employees" from emp;
Average salary of 14 employees
--------------------------------------
2073.21429
SQL>
However, if you're already using Apex, switch to GUI and create a page which will let you format the result any way you want (using colors, large font, bold letters, whatever). SQL*Plus and its descendants are kind of restrictive when such things should be done.

Related

A simple question about Oracle database format column

On Oracle, to set the output more nice using sqlplus we did this
column author format a15
column editor format a15
column title format a15...
The question is simple: set column size for 3 column is easy, but if we had 7 or more column? Is possible to set a default column size for all columns?
Well, it is possible - for numbers. You have 3 options available:
COLUMN FORMAT takes precedence over
SET NUMFORMAT which takes precedence over
SET NUMWIDTH
For example:
SQL> set numwidth 2
SQL> select sal from emp where rownum <= 2;
SAL
---
##
##
SQL> set numformat $9990d0
SQL> select sal from emp where rownum <= 2;
SAL
--------
$1000,0
$1600,0
SQL> col sal format $999g990d00
SQL> select sal from emp where rownum <= 2;
SAL
------------
$1.000,00
$1.600,00
SQL>
No such luck for other datatypes, though.
No. By default, the display length of a string column is the size of the column in the database. So if a column is defined, for example, as varchar2(100), then SQL*Plus reserves 100 characters in the resultset. Specific rules apply for datatypes such as dates, CLOB or else, but this is probably not what you are asking for here.
If you want to change that, it needs to be done on a column-per-column basis.
From the documentation:
The default width of datatype columns is the width of the column in the database.
You can change the displayed width of a datatype or DATE, by using the COLUMN command with a format model consisting of the letter A (for alphanumeric) followed by a number representing the width of the column in characters.
Within the COLUMN command, identify the column you want to format and the model you want to use.

What am I doing wrong in the following SQL code?

SQL> set serverout on
SQL> CREATE PROCEDURE find employees
2 BEGIN
3 if Department_ID < 50 from Employees
4 THEN
5 RETURN select Employee_ID, First_Name, Last_Name, Department_ID from Employees where Department_ID < 50;
6 ELSE
7 RETURN select Employee_ID, First_Name, Last_Name, Department_ID from Employees where Department_ID > 50;
8 END IF;
9 /
Warning: Procedure created with compilation errors.
Nothing about this makes sense.
Return can only return integers and is used only for returning error codes.
This is an incorrect use of If as well in two different ways. Where are you getting the value of Department_id? And look up the syntax for If as you are way off.
Of course you wouldn't have line numbers in the actual stored proc.
It is a poor practice to name a proc with spaces, do not do that.
A number of issues I can see (assuming per the tag that this is MS-SQL):
find employees isn't a valid proc name, due to the space. To absolutely force it to accept the space (warning: bad idea!!) you could surround it in brackets like [find employees] but I would definitely recommend something like find_employees instead.
You are missing an END to signify the end of your proc.
You don't use RETURN inside a stored proc, only inside a function. Are you trying to pass a result set to whatever called it (in which case you'd need a "table-valued function")? Or just display the results?
Are you trying to pass in Department_ID? In other words, to give it a different Department_ID each time you run? In that case you'll need a #Department_ID parameter or something. Or is it getting it from a table?
I can't fathom your business logic, it makes no sense. Why are you returning two different lists of employees? Are you trying to count how many employees belong to each dept? Is this some kind of "paging" logic (retrieving only 50 employees at a time)?
Your IF syntax is way off. should be something like IF #Department_ID < 50 (for a parameter) or maybe IF (SELECT COUNT(*) FROM Employees WHERE Department_ID = #Department_ID) > 50 or something, but again, I'm having a hard time trying to figure out what you're trying to do.
SQL doesn't use END IF. Look up the syntax for single-line IF ELSE statements and multi-line IF ELSE statements.
Warning: Procedure created with compilation errors.
Yep.
there is no END to the CREATE statement...
There is no definition of department_id...
there are no parameters declared for the IF statement to work on...
The function name has a space in it...

When I open a View source, the clause "NOFORCE" disappear

I created a random View like this:
CREATE OR REPLACE NOFORCE VIEW TEMP_VIEW (first_name, age) AS
SELECT 'Gladiolus' first_name, 23 age
FROM dual
/
And I check it out:
SELECT * FROM temp_view
/
FIRST_NAME AGE
---------- ----------
Gladiolus 23
Now, when I open the source to edit it (with PLSQL Developer and SQL Navigator) I get this:
CREATE OR REPLACE VIEW TEMP_VIEW AS
SELECT 'Gladiolus' first_name, 23 age
FROM dual;
The alias (first_name, age) is ommited because they are equal to the columns of the subquery.
But can you tell me why the clause NOFORCE is also not showed?
Thank you!!
Some keywords control how objects are created but they are not a part of the object definition. Oracle does not always care "how" an object was created and does not always store the options used to create it.
When Oracle and 3rd party tools create a DDL statement they must guess which of those options you would like to use. It's not uncommon for the tools to make different guesses, or to have small syntax differences.
(This is one of the many reasons to store all DDL in version-controlled text files instead of the database. What you put into the database will NOT be the same as what you get out.)
To use your example another way:
SQL> CREATE NOFORCE VIEW TEMP_VIEW (first_name, age) AS
2 SELECT 'Gladiolus' first_name, 23 age
3 FROM dual
4 /
View created.
The view was created with NOFORCE and without an OR REPLACE. But the DDL generated by DBMS_METADATA.GET_DDL contains FORCE, OR REPLACE and other differences:
SQL> select dbms_metadata.get_ddl('VIEW', 'TEMP_VIEW') from dual;
DBMS_METADATA.GET_DDL('VIEW','TEMP_VIEW')
--------------------------------------------------------------------------------
CREATE OR REPLACE FORCE EDITIONABLE VIEW "JHELLER"."TEMP_VIEW" ("FIRST_NAME",
"AGE") AS
SELECT 'Gladiolus' first_name, 23 age
FROM dual
The real "source" of the object does not contain any of the CREATE options at all:
SQL> select text from dba_views where view_name = 'TEMP_VIEW';
TEXT
--------------------------------------------------------------------------------
SELECT 'Gladiolus' first_name, 23 age
FROM dual
Here's an incomplete list of things that may be different when you regenerate code from an Oracle databases:
OR REPLACE
FORCE|NOFORCE
AND RESOLVE|AND COMPILE (for Java)
Whitespace
Case
Column Lists
Double Quotes
Terminators
Different DDL generators allow you to control some of those options, but in my experience none of them let you completely control all of them.
NOFORCE is the default, so keeping it is redundant.

List the employees whose name starts with 'S' and ends with 'S'?

I know the SQL LIKE statement.
I want to implement SQL LIKE statement in Informatica.
The goal is list all the employees whose name starts with 'S' and ends with 'S'.
select ENAME from EMP where ENAME LIKE ('S%') and ENAME LIKE('%S');
It looks like Informatica does not have a LIKE equivalent available. You can use REG_MATCH and insert in a regular expression that will match for starts with S and ends with S. Example Below:
REG_MATCH(ENAME,'[S^]+\w+[S$]')
RegExr Link: http://regexr.com/3b17b

Show the structure of the table in SQL

Can someone explain things a little better to me? How do I show the structure of a table?
I run the select * from table; and of course it displays all that's in the table. But, I am being asked to show the structure of the table. What does that mean, and what is the command?
Here's my table below.
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
Try this out: describe table_name
To list columns and data types, I typically use
SELECT COLUMN_NAME, DATA_TYPE FROM ALL_TAB_COLUMNS WHERE TABLE_NAME='your_table_name';
It's been a while since I've worked with Oracle though. ALL_TAB_COLUMNS might actually be ALL_TAB_COLS.
If you need to display the full CREATE TABLE statement, see How to get Oracle create table statement in SQL*Plus
You can use sqlplus command describe <SCHEMA_OWNER.TABLE>
https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12019.htm