'Tidy up' Oracle SQL report output - sql

I am writing some SQL to output reports via SQL*Plus (Oracle Reflection). The output files (xlsx or lst) contain a lot of information that isn't needed in this instance, like below:
Session altered.
Enter value for 1: LIF
old 3: where a.group = '&&1'
new 3: where a.group = '123'
URN |Title |Forename |Middle Name | Surname
--------------------------------------------------------------------------------------------------
123 | Mx | Smith |Bryn | Paul
Rows Selected 1
I am looking to suppress the leading rows so that 'URN' is located in cells A1, the row of '-' separating the headers from the data and finally the 'rows selected' output.
Thanks in advance!

Try:
SET HEADING OFF
More info on the options here.
Edit: The option for removing the count of rows selected at the end is
SET FEEDBACK OFF
just noticed it in the question.

Related

How can I extract comma delimited values from one column and put them each in separate column in Google Data Studio?

Update: 1,2,3 are just examples it can also be 4,24,53
I have the following setup:
I store Data in BigQuery and use BigQuery as data source for my Data Studio project.
I have a column called Alarms and the data inside that column is as follow: it can be empty or 1 or 1,2 or 1,2,3 or 5,43,60 and so on. If it's empty or has 1 value then there is nothing to worry about, but if there are 2 or more values I have to do something.
name
Alarm
Mark
John
1
Eddie
1,2
Peter
1,2,3
What I need is to be able to put every value in a separate column or create a dropdown or something.
For example something like the table below or two drop down menus one to select the name and the other shows the alarms. (I prefer the drop downs).
name
Alarm
Mark
John
1
Eddie
1
2
Peter
1
2
3
Here I select Peter and the alarm drop down shows 3 alarms. or for Eddie it just shows 2 alarms and so on.
I read something about regex but I don't really understand how to put it to the test.
I found this online: (.+?)(?:,|$) but I don't know how to capture the output.
What I need is to be able to put every value in a separate column
Consider below approach
select * from (
select * except(alarm)
from your_table,
unnest(split(alarm)) flag with offset
)
pivot (min(flag) as alarm for offset in (0,1,2,3,4))
If applied to sample data in your question -output is

How do I select a SQL dataset where values in the first row are the column names?

I have data that looks like this:
ID RowType Col_1 Col_2 Col_3 ... Col_n
1 HDR FirstName LastName Birthdate
2 DTL Steve Bramblet 1989-01-01
3 DTL Bob Marley 1967-03-12
4 DTL Mickey Mouse 1921-04-25
And I want to return a table or dataset that looks like this:
ID FirstName LastName Birthdate
2 Steve Bramblet 1989-01-01
3 Bob Marley 1967-03-12
4 Mickey Mouse 1921-04-25
where n = 255 (so there's a limit of 255 Col_ fields)
***EDIT: The data in the HDR row is arbitrary so I'm just using FirstName, LastName, Birthdate as examples. This is why I thought it will need to be dynamic SQL since the column names I want to end up with will change based on the values in the HDR row. THX! ***
If there's a purely SQL solution that is what I'm after. It's going into an ETL process (SSIS) so I could use a Script task if all else fails.
Even if I could return a single row that would be a solution. I was thinking there might be a dynamic sql solution for something like this:
select Col_1 as FirstName, Col_2 as LastName, Col_3 as Birthdate
Not sure if your first data snippet is already in a oracle table or not but it is in a CSV file then you have option during loading to skip headers.
If data is already in table then you can use UNION to get desired result
Select * from table name where rowtype=‘HRD’
union
select * from table name where rowtype=‘DTL’
If you need First Name etc as Column header then you need not to do anything. Design destination table columns as per your requirement.
Sorry, posted an answer but I completely misread that you had your desired column headers as data in the source table.
One trivial solution (though it requires more IO) would be to dump the table data to a flat file without headers, then read it back in, but this time tell SSIS that the first row has headers, and ignore the RowType column. Make sure you sort the data correctly before writing it out to the intermediate file!
To dump to a file without headers, you have to set ColumnNamesInFirstDataRow to false. Set this in the properties window, not by editing the connection. More info in this thread
If you have a lot of data, this is obviously very inefficient.
Try the following using row_number. Here is the demo.
with cte as
(
select
*,
row_number() over (order by id) as rn
from myTable
)
select
ID,
Col_1 as FirstName,
Col_2 as LastName,
Col_3 as Birthdate
from cte
where rn > 1
output:
| id | firstname | lastname | birthdate |
| --- | --------- | -------- | ---------- |
| 2 | Steve | Bramblet | 1989-01-01 |
| 3 | Bob | Marley | 1967-03-12 |
| 4 | Mickey | Mouse | 1921-04-25 |
Oh, well. There is a pure SSIS approach, assumed the source is a SQL table. Here it is, rather sketchy.
Create a Variable oColSet with type Object, and 255 variables of type String and names sColName_1, sColName_2 ... sColName_255.
Create a SQL Task with query like select top(1) Col_1, Col_2, ... Col_255 from Src where RowType = 'HDR', set task properties ResultSet = Full Result Set, on result set tab - set Result Name to 0 and Variable Name to oColSet.
Add ForEach Loop enumerator, set it as ForEach ADO Enumerator, ADO object source variable - set to oColSet, Enumeration mode = Rows in the first table. Then, on the Variable Mappings tab - define as such example (Variable - Index) - sColName_1 - 0, sColName_2 - 1, ... sColName_255 - 254.
Create a variable sSQLQuery with type String and Variable Expression like
"SELECT Col_1 AS ["+#[User::sColName_1]+"],
Col_2 AS ["+#[User::sColName_2]+"],
...
Col_255 AS ["+#[User::sColName_255]+"]
FROM Src WHERE RowType='DTL'"
In the ForEach Loop - add your dataflow, in the OLEDB Source - set Data access mode to SQL command from variable and provide variable name User::sSQLQuery. On the Data Flow itself - set DelayValidation=true.
The main idea of this design - retrieve all column names and store it in temp variable (step 2). Then step 3 does parsing and places all results into corresponding variables, 1 column (0th) - into sColName_1 etc. Step 4 defines a SQL command as an expression, which is evaluated every time when the variable is read. Finally, in the ForEach Loop (where parsing is done) - you perform your dataflow.
Limitations of SSIS - data types and column names should be the same at runtime as at design time. If you need to further store your dataset into SQL - let me know, so I could adjust the proposed solution.

How to map two column using another column data

I have Five columns.
E.g.
Column1: Name
Column2: surname
Column3: mapping
Column4: Mapped data
Columns contain data like
Name Surname Mapping Name1 Surname1
1 ABC 1 AAAA 3 ABC QQQQ
2 XYZ 2 XXXX 1 XYZ AAAA
3 OPQ 3 QQQQ 4 OPQ RRRR
4 RST 4 RRRR 2 RST XXXX
Now my aim is to map name column to surname by using mapping column and result should be stored at Name1 and Surname1 column. I have more data in Name and Surname column, by writing number in Mapping column it will automatically map the surname to Name (the choice is given to user for entering number in mapped column then map the data accordingly) and result should be copied in Name1 and Surname1.
I am not getting any idea to achieve this using VBA. coding Plz help me.....
Amar, there are certainly plenty of ways to go about this using Excel's built in functions, however, since you asked about a VBA solution, here you go:
Function Map(n)
Map = Cells(n + 1, 2)
End Function
Placing the above code into the VBA editor of your project will allow you to use this custom function in the same way you would any of Excel's builtin functions. That is, entering =Map(C3) into any cell should give you the result you're after (where C3 is the cell containing your mapping number). The function works by returning the data in [row n (defined in your mapping column) +1 (to account for the header row); column 2 (the column containing your surname)]. The data in column "Name1" will always be the same as that in column "Name" (so it seems). So the function in your "Name1" column would simply be =A2
If this does not solve your problem, or you need further guidance, please let me know.
Supplement
#Amar, the comment by #freakfeuer is spot on. VBA is really overkill for something as simple as this and, as he points out, portability and security are both significant drawbacks. Offset is a fine alternative.

Excel [VBA] find duplicate data and delete the oldest one

I have a problem in MS Excel. I´ve a spreadsheet with data like this:
Name | timestamp
------------------------
Smith | 12.05.2015
Smith | 01.01.2015
Smith | 10.05.2015
Simpson | 14.04.2015
Simpson | 10.02.2015
Simpson | 21.03.2015
Simpson | 02.01.2015
The data I´ve is much bigger and komplex and there are duplicates with different timestamps. Now I want to delete the oldes ones and want an output like this:
Name | timestamp
Smith | 12.05.2015
Simpson | 14.04.2015
I know how to remove duplicates, but in this case it´s a little bit different. I hope you can help me to solve the problem.
You may not need VBA.
In my experience the Excel Remove Duplicates code works to remove the first encountered duplicates in a list.
So sort your data by Name ascending and timestamp descending, then remove the duplicates from the Name field only.
You should be left with the most recent names.
I did a bit of testing, and Range.RemoveDuplicates appears to keep the first entry for each duplicate value (at least in a sorted range, which you're going to use). Here's my solution:
Sub SortAndCondense()
'This subroutine sorts a table by name and secondarily by descending date. It then removes
'all duplicates in the name column. By sorting the dates in descending order, only the most
'recent entries for each name are preserved
Dim wrkSht As Worksheet
Set wrkSht = ThisWorkbook.Worksheets("Sheet1")
Dim dateTable As Range
Dim header1 As Range, header2 As Range
Set dateTable = wrkSht.Range("A2:B7") 'insert your actual table range; modify as necessary for column headers
Set header1 = wrkSht.Range("A2")
Set header2 = wrkSht.Range("B2")
'sort the column primarily by name, and secondarily by descending date. The order in which the names are sorted
'is irrelevant.
dateTable.Sort Key1:=header1, Key2:=header2, Order2:=xlDescending
'remove all duplicate names. The way remove duplicates works (so far as I can tell) is that it keeps only the
'topmost entry for each duplicate column.
dateTable.RemoveDuplicates 1
End Sub

"update" sql for remove same string from all rows

My website attacked and hackers adds same string to all of my rows.
For example if the value of a row was "True value" they changed it to "True Value HACKED STRING ... HACKED by .. "
Unfortunately my site have lots of data and I can't change them one by one, but fortunately same data adds to all rows.
I want an SQL statement that removes all HACKED STRING from all rows.
You can do that quickly by removing the string with REPLACE function
Example TableA
id | Name
--------------
1 | Good HACKED BY XX
2 | We know HACKED BY XX
3 | Goodbye HACKED BY XX
Sql
UPDATE TableA
SET Name = REPLACE(Name, ' HACKED BY XX', '');
This will make you table look like this
id | Name
--------------
1 | Good
2 | We know
3 | Goodbye