Db2: how to format output? - db2

I don't like the db2 console output
db2 => SELECT city,SUM(sales) as sum from offices group by city;
CITY SUM
---------------------------------------------------------------------------------------------------- ---------------------------------
Rome 14000,
London 19000,
I would prefer something like this
db2 => SELECT city,SUM(sales) as sum from offices group by city;
CITY SUM
------------------------
Rome 14000
London 19000
On Oracle I use
set feedback on;
set linesize 9000
set colsep |
column column1 format a30
column column2 format a20
....
And I get a nice output
How for format the columns on DB2?
I'm interested in max size(a30 mean display 30 chars).

Formatting of SQL output is a job for the client application.
Your question shows use of the legacy interactive Db2 Command-Line-Processor (Db2 CLP) application supplied with some Db2 clients. The Db2 CLP has limited formatting functionality compared to Oracle SQL*Plus.
However, if you are used to Oracle SQL*Plus style formatting, there is a tool supplied with some Db2 clients called clpplus which emulates SQL*Plus. This means you don't need to learn new syntax for formatting and many other actions.
You can use clpplus instead of the interactive Db2 CLP, and clpplus lets you use many of the features and syntax of Oracle SQL*Plus with Db2 databases.

I have found a nice workaround using substr of SQL syntax
Without substr
select title,year from titles;
TITLE YEAR
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------
Fantasia 1940
EEK!
With using of substr
select substr(title,1,19) as title, substr(year,1,4) as year from titles;
TITLE YEAR
-------------------------------------- ----
FANTASIA 1940
Good!

Related

Group By expression in Oracle 19c

I am installing a database schema in Oracle 19c, and the installation scripts have been used repeatedly in Oracle 12 without problems.
My problem with 19c is when it runs our views script, it throws an on at some of views. The error we are seeing the not a group by expression.
We have a few views where for example we have something like this:
SELECT name, TRUNC(date) as Day
FROM sometable
GROUP BY name, TRUNC(date)
It is pointing the error at the select as though it doesn't see that the field is already in the group by expression.
As said, these queries work fine in Oracle 12 for years, it is only now when moving to 19 that we are seeing problems.
Is this a bug in 19c or does something need to be applied?
19c, you say? Can't reproduce it.
SQL> select banner from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Table you used (so that you wouldn't say that this is the culprit) (obviously, date is an invalid column name; that's reserved for the date datatype).
SQL> create table sometable as
2 select 'Little' name, sysdate datum
3 from dual
4 connect by level <= 3;
Table created.
Does query itself work? Yes:
SQL> select name, trunc(datum) as day
2 from sometable
3 group by name, trunc(datum);
NAME DAY
------ --------
Little 26.01.22
Note that - as you aren't aggregating anything - you could have used DISTINCT instead of GROUP BY:
SQL> select DISTINCT name, trunc(datum) as day
2 from sometable;
NAME DAY
------ --------
Little 26.01.22
Can I create a view? Yes:
SQL> create view v_sometable as
2 select name, trunc(datum) as day
3 from sometable
4 group by name, trunc(datum);
View created.
SQL>
As I said, I can't reproduce it.
Please, copy/paste your own SQL*Plus session (just like I did) so that we'd see what exactly you did and how Oracle responded.

Add Heading to a group of columns in Oracle SQL

Oracle 11g. Oracle Apex 5.1
I need to Merge the columns without merging the data and Add a column heading in Oracle Apex Interactive Report.
For Example
I have a table like this:
I want the table output like this:
How can I achieve the output in Report Select Statement?
If I am using below query in Oracle Apex Interactive Report:
TITLE LEFT ' amount_column Quantity_column'
SELECT Date, Amount1, Amount2, Amount3, Quantity1, Quantity2
FROM table_name;
I am getting error as: ORA-20001: Query must begin with SELECT or WITH.
In oracle Apex 5.1 we can create such groups in Interactive Grid(IG).
To create a group, steps are:
Go to Attribute of IG -> create Group -> add a name to group.
To assign a group on column, steps are:
go to particular column(s) name -> under layout property -> select group name
Save and run the page and it will work.
If you are running the query to get a SQL/Plus style textual output (using Crtl-F5 / run-as-script within SQL Developer) then you can use the commands for formatting SQL*Plus reports such as COLUMN and TTITLE to make it appear like your desired result:
Something like (untested):
COLUMN "Date" FORMAT A9
COLUMN Amount1 FORMAT 9999.99
COLUMN Amount2 FORMAT 9999.99
COLUMN Amount3 FORMAT 9999.99
COLUMN Quantity1 FORMAT 999999999
COLUMN Quantity2 FORMAT 999999999
TTITLE LEFT ' Amount column Quantity Column'
SELECT "Date", Amount1, Amount2, Amount3, Quantity1, Quantity2
FROM table_name;
If you want to do it in the grid (using F5 to run the query within SQL Developer) then you are out of luck and it is not possible.

Can we exclude match with few strings in oracle regexp_like()?

Background Knowledge:
We can't use (?!) to exclude, since, regexp_like() doesn't support negative lookahead.
I don't want to exclude using 'NOT REGEXP_LIKE()'
[^] can negate a single character only but not a string
Question:
Interested to know if we have any alternative to change the regular expression itself being passed to oracle regexp_like().
Example scenario to explain:
Regexp - "STANDARD.*TIME" when used in regexp_like() would match all time zones containing both words STANDARD and TIME. Say I want to exclude 'INDIAN STANDARD TIME', 'ATLANTIC STANDARD TIME', 'IRISH STANDARD TIME' from the matched time zones
I would be interested to know why using 'NOT' is out of the question. But if you are looking for a regex solution for the fun of it, I don't think REGEXP_LIKE is going to work as the Oracle flavor does not support negative look-aheads. However, thinking outside of the box a little, and knowing that REGEX_REPLACE returns NULL if the pattern is not found, you could do something like this (although just because you can does not mean you should and I would use NOT with REGEXP_LIKE):
SQL> with tbl(str) as (
select 'INDIAN STANDARD TIME' from dual union all
select 'ATLANTIC STANDARD TIME' from dual union all
select 'IRISH STANDARD TIME' from dual union all
select 'EASTERN STANDARD TIME' from dual union all
select 'PST STANDARD TIME' from dual union all
select 'CST STANDARD TIME' from dual
)
select str
from tbl
where str = regexp_replace(str, '^(INDIAN|ATLANTIC|IRISH) STANDARD.*TIME', 'DO NOT WANT THESE');
STR
----------------------
EASTERN STANDARD TIME
PST STANDARD TIME
CST STANDARD TIME
SQL>
So this replaces the strings you don't want then compares them. Since the match is not found the select does not return them. Still not as clean as:
select str
from tbl
where NOT regexp_like(str, '^(INDIAN|ATLANTIC|IRISH) STANDARD.*TIME');

how i can select the missing date from oracle table

I have a table emp_attn (emp_name varchar2(30),attn_dt date) values like
select * from emp_attn;
result like
EMP_NAME ATTN_DT
-------------------- ----------
SAM 02/05/2013
SAM 03/05/2013
SAM 07/05/2013
SAM 08/05/2013
SAM 13/05/2013
SAM 14/05/2013
SAM 17/05/2013
SAM 18/05/2013
SAM 19/05/2013
SAM 20/05/2013
SAM 21/05/2013
SAM 22/05/2013
SAM 23/05/2013
SAM 24/05/2013
SAM 25/05/2013
RAM 01/05/2013
RAM 03/05/2013
RAM 07/05/2013
RAM 08/05/2013
RAM 10/05/2013
RAM 11/05/2013
RAM 14/05/2013
RAM 18/05/2013
RAM 19/05/2013
RAM 20/05/2013
RAM 23/05/2013
RAM 24/05/2013
RAM 25/05/2013
I need the missing attn_dt and name from this table
You can use dual table for find out missing dates.
Consider below example
http://sqlfiddle.com/#!4/5cbc7/10
Here test table has 10 rows.
Select dat from ( SELECT to_char(SYSDATE + LEVEL, 'dd/MM/yyyy') dat
FROM DUAL CONNECT BY LEVEL <= 12 -- You can change as per your date range
) a where dat not in (select dates from test);
The above select query returns give the result set of not available dates in test table.
You can get the missed date by passing two parameters on this query.
SYSDATE - Give your start date
LEVEL (In where condition) - Give as per your date range.

Table Aggregation strategy (SSIS / Stored procedure / SSRS)

I have a table with roughly 7,000,000 records.
It's very flat and for sake of argument it has 3 columns I wish to aggregate on. This aggregation should very simply create a count /pivot of each instance of that value.
E.G
Company Status Year
Hatstand Open 2011
Hatstand Closed 2011
Moonbase Open 2011
Would produce
Count of Hatstand **2**
Count of Hatstand Open **1**
Count of Hatstand Open 2011 **1**
So it's a very simple count of each "branch" of data.
My first choice was to use a SSRS Matrix control. Which when testing with a small dataset worked really well. However when using a the full data-set would not run.
What is the "correct" way to approach this problem?
Should I pre-aggregate via a stored procedure or SSIS job?
Or should I continue with the SSRS route and try to refine my query?
Thanks
T-SQL is preferred way to go if You are using SQL Server 2005 or 2008.
If You are using SQL Server 2005 or 2008 You can try:
SELECT *, COUNT(*) FROM TBL
GROUP BY COMPANY, STATUS, YEAR
WITH ROLLUP -- or WITH CUBE
If You are using SQL Server 2008 You can try with :
SELECT *, COUNT(*) FROM A
GROUP BY
GROUPING SETS (
(COMPANY),
(COMPANY, STATUS),
(COMPANY, STATUS, YEAR)
)
For details about GROUP BY WITH ROLLUP/CUBE and GROUPING SETS take a look at GROUP BY.