I'm trying to export the result of a query in db2 to file, but the result like:
+000000869836.|+00000000000001401.
+000000978137.|+00000000000000511.
What can I do to obtain the following result:
869836.|1401.
978137.|511.
My current query:
EXPORT TO /tmp/tmp.tmp OF del modified by NOCHARDEL coldel|
select
iv.bpd_instance_id,
max(case when alias = 'abc' then INT_VALUE else null end) as A,
max(case when alias = 'xyz' then STRING_VALUE else null end) as X,
from lsw_bpd_instance_variables iv
where bpd_instance_id in ($instancesDB)
group by iv.bpd_instance_id
with ur
The default behavior of DB2's EXPORT utility is to format any DECIMAL value with a leading positive/negative sign and pad it with leading zeros. To override this behavior, specify the DECPLUSBLANK and STRIPLZEROS options in your MODIFIED BY clause, or CAST the DECIMAL values to some other type in your SELECT statement.
Related
event_params is a repeated record. Its key values can be
firebase_event_origin, engagement_time_msec, firebase_screen, ...
Each key has a number of optional values according to the data type:
string_value, int_value, ...
I want to convert the key into a column and that the value will populate it.
For example: the key firebase_screen will be converted into a column firebase_screen with a value of webview screen. Same for all the other repeated records in the table.
I'm not sure if the UNNEST is the right solution here since it breaks it down into records instead of columns.
The screenshots of schema and the table I used for this example:
You need to unnest first, then group the data again.
Please replace the bracket in FROM ( ... ) with your table.
SELECT
date,
ANY_VALUE(CASE WHEN t.key="firebase_screen" THEN t.string_value ELSE NULL END) AS firebase_screen,
ANY_VALUE(CASE WHEN t.key="ga_session_number" THEN t.int_value ELSE NULL END) AS ga_session_number,
FROM (
SELECT
1 date,
[STRUCT("firebase_screen" AS key,
"webs" AS string_value,
NULL AS int_value),
STRUCT("ga_session_number" AS key,
NULL,
6 AS int_value) ] AS event_params ) AS tbl,
UNNEST(tbl.event_params) AS t
GROUP BY 1
I am quite new to u-sql, trying to solve
str1=\global\europe\Moscow\12345\File1.txt
str2=\global.bee.com\europe\Moscow\12345\File1.txt
str3=\global\europe\amsterdam\54321\File1.Rvt
str4=\global.bee.com\europe\amsterdam\12345\File1.Rvt
case1:
how do i get just "\europe\Moscow\12345\File1.txt" from the strings variable str1 & str2, i want to just take ("\europe\Moscow\12345\File1.txt") from str1 and str2 then "Groupby(\global\europe\Moscow\12345)" and take the count of distinct files from the path (""\europe\Moscow\12345\")
so the output would be something like this:
distinct_filesby_Location_Date
to solve the above case i tried the below u-sql code but not quite sure whether i am writing the right script or not:
#inArray = SELECT new SQL.ARRAY<string>(
filepath.Contains("\\europe")) AS path
FROM #t;
#filesbyloc =
SELECT [ID],
path.Trim() AS path1
FROM #inArray
CROSS APPLY
EXPLODE(path1) AS r(location);
OUTPUT #filesbyloc
TO "/Outputs/distinctfilesbylocation.tsv"
USING Outputters.Tsv();
any help would you greatly appreciated.
One approach to this is to put all the strings you want to work with in a file, eg strings.txt and save it in your U-SQL input folder. Also have a file with the cities in you want to match, eg cities.txt. Then try the following U-SQL script:
#input =
EXTRACT filepath string
FROM "/input/strings.txt"
USING Extractors.Tsv();
// Give the strings a row-number
#input =
SELECT ROW_NUMBER() OVER() AS rn,
filepath
FROM #input;
// Get the cities
#cities =
EXTRACT city string
FROM "/input/cities.txt"
USING Extractors.Tsv();
// Ensure there is a lower-case version of city for matching / joining
#cities =
SELECT city,
city.ToLower() AS lowercase_city
FROM #cities;
// Explode the filepath into separate rows
#working =
SELECT rn,
new SQL.ARRAY<string>(filepath.Split('\\')) AS pathElement
FROM #input AS i;
// Explode the filepath string, also changing to lower case
#working =
SELECT rn,
x.pathElement.ToLower() AS pathElement
FROM #working AS i
CROSS APPLY
EXPLODE(pathElement) AS x(pathElement);
// Create the output query, joining on lower case city name, display, normal case name
#output =
SELECT c.city,
COUNT( * ) AS records
FROM #working AS w
INNER JOIN
#cities AS c
ON w.pathElement == c.lowercase_city
GROUP BY c.city;
// Output the result
OUTPUT #output TO "/output/output.txt"
USING Outputters.Tsv();
//OUTPUT #working TO "/output/output2.txt"
//USING Outputters.Tsv();
My results:
HTH
Taking the liberty to format your input file as TSV file, and not knowing all the column semantics, here is a way to write your query. Please note that I made the assumptions as provided in the comments.
#d =
EXTRACT path string,
user string,
num1 int,
num2 int,
start_date string,
end_date string,
flag string,
year int,
s string,
another_date string
FROM #"\users\temp\citypaths.txt"
USING Extractors.Tsv(encoding: Encoding.Unicode);
// I assume that you have only one DateTime format culture in your file.
// If it becomes dependent on the region or city as expressed in the path, you need to add a lookup.
#d =
SELECT new SqlArray<string>(path.Split('\\')) AS steps,
DateTime.Parse(end_date, new CultureInfo("fr-FR", false)).Date.ToString("yyyy-MM-dd") AS end_date
FROM #d;
// This assumes your paths have a fixed formatting/mapping into the city
#d =
SELECT steps[4].ToLowerInvariant() AS city,
end_date
FROM #d;
#res =
SELECT city,
end_date,
COUNT( * ) AS count
FROM #d
GROUP BY city,
end_date;
OUTPUT #res
TO "/output/result.csv"
USING Outputters.Csv();
// Now let's pivot the date and count.
OUTPUT #res2
TO "/output/res2.csv"
USING Outputters.Csv();
#res2 =
SELECT city, MAP_AGG(end_date, count) AS date_count
FROM #res
GROUP BY city;
// This assumes you know exactly with dates you are looking for. Otherwise keep it in the first file representation.
#res2 =
SELECT city,
date_count["2016-11-21"]AS [2016-11-21],
date_count["2016-11-22"]AS [2016-11-22]
FROM #res2;
UPDATE AFTER RECEIVING SOME EXAMPLE DATA IN PRIVATE EMAIL:
Based on the data you sent me (after the extraction and counting of the cities that you either could do with the join as outlined in Bob's answer where you need to know your cities in advance, or with the taking the string from the city location in the path as in my example, where you do not need to know the cities in advance), you want to pivot the rowset city, count, date into the rowset date, city1, city2, ... were each row contains the date and the counts for each city.
You could easily adjust my example above by changing the calculations of #res2 in the following way:
// Now let's pivot the city and count.
#res2 = SELECT end_date, MAP_AGG(city, count) AS city_count
FROM #res
GROUP BY end_date;
// This assumes you know exactly with cities you are looking for. Otherwise keep it in the first file representation or use a script generation (see below).
#res2 =
SELECT end_date,
city_count["istanbul"]AS istanbul,
city_count["midlands"]AS midlands,
city_count["belfast"] AS belfast,
city_count["acoustics"] AS acoustics,
city_count["amsterdam"] AS amsterdam
FROM #res2;
Note that as in my example, you will need to enumerate all cities in the pivot statement by looking it up in the SQL.MAP column. If that is not known apriori, you will have to first submit a script that creates the script for you. For example, assuming your city, count, date rowset is in a file (or you could just duplicate the statements to generate the rowset in the generation script and the generated script), you could write it as the following script. Then take the result and submit it as the actual processing script.
// Get the rowset (could also be the actual calculation from the original file
#in = EXTRACT city string, count int?, date string
FROM "/users/temp/Revit_Last2Months_Results.tsv"
USING Extractors.Tsv();
// Generate the statements for the preparation of the data before the pivot
#stmts = SELECT * FROM (VALUES
( "#s1", "EXTRACT city string, count int?, date string FROM \"/users/temp/Revit_Last2Months_Results.tsv\" USING Extractors.Tsv();"),
( "#s2", "SELECT date, MAP_AGG(city, count) AS city_count FROM #s1 GROUP BY date;" )
) AS T( stmt_name, stmt);
// Now generate the statement doing the pivot
#cities = SELECT DISTINCT city FROM #in2;
#pivots =
SELECT "#s3" AS stmt_name, "SELECT date, "+String.Join(", ", ARRAY_AGG("city_count[\""+city+"\"] AS ["+city+"]"))+ " FROM #s2;" AS stmt
FROM #cities;
// Now generate the OUTPUT statement after the pivot. Note that the OUTPUT does not have a statement name.
#output =
SELECT "OUTPUT #s3 TO \"/output/pivot_gen.tsv\" USING Outputters.Tsv();" AS stmt
FROM (VALUES(1)) AS T(x);
// Now put the statements into one rowset. Note that null are ordering high in U-SQL
#result =
SELECT stmt_name, "=" AS assign, stmt FROM #stmts
UNION ALL SELECT stmt_name, "=" AS assign, stmt FROM #pivots
UNION ALL SELECT (string) null AS stmt_name, (string) null AS assign, stmt FROM #output;
// Now output the statements in order of the stmt_name
OUTPUT #result
TO "/pivot.usql"
ORDER BY stmt_name
USING Outputters.Text(delimiter:' ', quoting:false);
Now download the file and submit it.
In my Pl/Sql code , I have three variables v_var1 , v_operand , v_var2 whose values are populated based on some logic (v_var1 & v_var2 can be date , number , varchar. Associated Operand will be according to data type only). A sample would be
v_var1 = 10 , v_operand = '=' , v_var2 = 20.
Based on these value , I have to evaluate whether the condition "v_var1 -v_operand- v_var2"is true or false.
Ex :- with above values, I have to evaluate whether 10 equals 20 or not.
How can I achieve this ? Can I pass the whole string as '10 = 20' to some function and get the result as false?
One way I can think of is to write CASE statements for evaluating but can there be a better way ?
You could use dynamic SQL to do the evaluation as a filter on the dual table:
declare
v_var1 varchar2(10) := '10';
v_operand varchar2(10) := '=';
v_var2 varchar2(10) := '20';
l_result number;
begin
execute immediate 'select count(*) from dual where :var1 ' || v_operand || ' :var2'
into l_result using v_var1, v_var2;
if l_result = 1 then
dbms_output.put_line('True');
else
dbms_output.put_line('False');
end if;
end;
/
PL/SQL procedure successfully completed.
False
If the condition is true the count will get 1, otherwise it will get 0, and you can then test that via the local variable you select the count into.
Holding dates and numbers as strings isn't ideal, even temporarily, but might be OK as long as you convert to/from the real data types consistently, e.g. always explicitly converting dates with to_date and to_char and specifying the format masks.
I am doing a long to string conversion using java in following way.
Long longValue = 367L;
String str = Long.toString(longValue, 36).toUpperCase();
this is returning me as value A7. how can achieve this in doing oracle sql.
UPDATED:
Hi, I have analyzed how java code is working then wanted to implement the same thing in procedure.
First point is Input vaues. LONG and Radix. in my case Radix is 36. so i will have values from 1..9A...Z0 It picks up the values from this set only.
Second point Long value as input. we have to divide this value with radix. if the quotient is more than 36 again we need to divide.
For eaxmple 367 then my converted value is 10(quotient) 7(remainder) that is A7.
3672 converted value is 102 0 i need to do again for 102 that is 2 -6 so my final value will be 2-6 0 that is 2U0(- means reverse the order).
UPDATE 2:
Using oracle built in functions we can do this. this was solved by my friend and gave me a function.I want to thank my friend. this will give me an out put as follows.
367 then my converted value is 10(quotient) 7(remainder) that is *A*7.(I modified this to my requirement).
FUNCTION ENCODE_STRING(BASE_STRING IN VARCHAR2,
FROM_BASE IN NUMBER,
TO_BASE IN NUMBER)
RETURN VARCHAR2
IS
V_ENCODED_STRING VARCHAR(100);
BEGIN
WITH N1 AS (
SELECT SUM((CASE
WHEN C BETWEEN '0' AND '9'
THEN TO_NUMBER(C)
ELSE
ASCII(C) - ASCII('A') + 10
END) * POWER(FROM_BASE, LEN - RN)
) AS THE_NUM
FROM (SELECT SUBSTR(BASE_STRING, ROWNUM, 1) C, LENGTH(BASE_STRING) LEN, ROWNUM RN
FROM DUAL
CONNECT BY ROWNUM <= LENGTH(BASE_STRING))
),
N2 AS (
SELECT (CASE
WHEN N < 10
THEN TO_CHAR(N)
ELSE CHR(ASCII('A') + N - 10)
END) AS DIGI, RN
FROM (SELECT MOD(TRUNC(THE_NUM/POWER(TO_BASE, ROWNUM - 1)), TO_BASE) N, ROWNUM RN
FROM N1
CONNECT BY ROWNUM <= TRUNC(LOG(TO_BASE, THE_NUM)) + 1)
)
SELECT SYS_CONNECT_BY_PATH(DIGI, '*') INTO V_ENCODED_STRING
FROM N2
WHERE RN = 1
START WITH RN = (SELECT MAX(RN) FROM N2)
CONNECT BY RN = PRIOR RN - 1;
RETURN V_ENCODED_STRING;
IN PL/SQL (or Oracle SQL) you have the a function called TO_CHAR.
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions181.htm
It is not possible to do it in the pure SQL. You have to use PL/SQL.
Simple example how to do it PL/SQL:
CREATE TABLE long_tbl
(
long_col LONG
);
INSERT INTO long_tbl VALUES('How to convert the Long value to String using sql');
DECLARE
l_varchar VARCHAR2(32767);
BEGIN
SELECT long_col
INTO l_varchar
FROM long_tbl;
DBMS_OUTPUT.PUT_LINE(l_varchar);
END;
-- How to convert the Long value to String using sql
There is TO_LOB function but it can only by used when you insert data into table.
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions185.htm
You can apply this function only to a LONG or LONG RAW column, and
only in the select list of a subquery in an INSERT statement.
There is also other, more proper way to do it by using "dbms_sql.column_value_long" but this gets complicated (fetching of the LONG column and appending to the CLOB type.)
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htm#i1025399
(Oracle Database PL/SQL Packages and Types Reference)
From my ASP.NET application I am calling an INSERT stored procedure, there is a default value for one of the columns in the table that the INSERT procedure places the data into. How do I specify that I want the default value to be used instead? (Or do I have to specify the actual default value in my parameters)
SITUATIONAL TABLE:
Column 1: int
Column 2: string
Column 3: int default -1
SITUATIONAL STORED PROCEDURE
INSERT INTO TABLE
(Column 1, Column 2, Column 3)
VALUES
(?, ?, ?)
SITUATIONAL ASP.NET CODE
create paramter (Column 1, 12)
if (x = 0)
{create parameter (Column 2, "test")}
else
{
create parameter (Column 3, 24)
create parameter (Column 2, DBNull.Value)
}
Thank you for your help
Leave the column out of the insert clause, and you will get the default.
For example in your procedure:
IF condition
INSERT INTO Y (X) VALUES(1); -- will use defaults
ELSE
INSERT INTO Y (W, X) VALUES(1, 2) -- won't use default for W
You can use the default keyword.
CREATE TABLE #T
(
i int default 12,
j int
)
INSERT INTO #T (i,j) VALUES (DEFAULT, 10)
SELECT i,j FROM #T
DROP TABLE #T
What aboutif (somecondition) { // User another value for c2
query = "insert into table_name (c1, c2) values (1, 2)";
} else { // User the column c2 default value
query = "insert into table_name (c1) values (1)";
}
In the stored procedure, you can set the parameter to have a default value itself, so that if you leave that parameter out of your application code, the procedure will substitute a default value.
#field_with_def_value int = -1,
etc...
If you want, you could set that default to the field's default value and be done with it. But it -might- be safer to test for that default value in the sproc and then conditionally call an INSERT that does the insert with or without that field's value. This way if the default is changed, you don't need to change your application or sproc code