Convert Salesforce IDs from 15 digit to 18 digit using sql code/function - sql

We are currently pulling in data from SalesForce to SQL Database tables. There are 2 custom fields on different objects that were created for the Lead ID and a look up for which event/task is linked (this can be an account id, contact id, or lead id). Both of these are pulling over the 15 digit ID.
I am trying to find out if there is any SQL code or a SQL function that will allow me to convert that 15 digit to an 18 digit ID.
I need to have that 18 digit ID to join back to the other objects.
We have already tried using the CASESAFEID(Id) function in SalesForce, but with the API that was already set up and the visibility levels our particular ETL is not showing that field. Also, we would need to get a consultant to mess with the look up column.
I would like to take the 15 digit ID and convert it to the 18 digit code. If the SalesforceID is 0035000002tAzbu, how do I get the converted 18 digit value to be 0035000002tAzbuACC. I need to get that last 3 digits using SQL query or SQL function.

you could write a custom function in your sql database.
e.g. in snowflake, you can make a function like this
CREATE OR REPLACE FUNCTION dw.my_schema.f_sfdc_ch15_to_ch18("txt" string)
RETURNS string
LANGUAGE JAVASCRIPT
AS '
if ( txt == undefined || txt == "" || typeof txt == "undefined" || txt == null) {
return ;
} else {
var id15, id18;
if (txt.length == 18) {
return txt;
} else if (txt.length == 15) {
id15 = [txt.trim()];
} else {
return "";
}
for ( var x=0; x < id15.length; x++ ) {
var s = "";
for ( var i=0; i<3; i++) {
var f = 0;
for (var j=0; j<5; j++) {
var c = id15[x].charAt(i*5+j);
if (c>="A" && c<="Z") {
f+=1<<j;
}
}
s += "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345".charAt(f);
}
id18 = id15[x]+s;
}
}
return id18.toString();
';
and use it like this
select dw.my_schema.f_sfdc_ch15_to_ch18(id15) from mytable;

This value can be computed. Check out this flowchart.
Source: https://stackoverflow.com/a/29299786/3135974

Related

Return values of #All of functions in podio calculation fields

I have 5 contacts connected to a company, and i am trying to sort out the ones that does not have an email with the code below.
var mailArray = #All of Email with nulls
var temp = new Array()
for (var i = 0; i < mailArray.length; i++) {
if (mailArray[i].value == null) {
temp.push("null")
}
else {
temp.push("correct")
}
}
temp.join(" ")
Right now i am just pushing the strings to make sure that the flow is correct, it however returns
null null null null null
when it should return
null correct correct null null
since the second and third contact has emails. Can anyone help me or give me a hint, as how to use the return value of the #All of function.
I just want to make sure what you are referring to on the emails. Is it an email field in the contacts app, or is it a text field that is called 'email'? If you are using an email field, then the value at your [i] index is actually another object and not just a string yet. Although it doesn't matter if you are just checking for something existing, but personally I'd like to know which contacts do have emails in the output.
If it is just a text field, then you have a problem with the conditional statement. It should be === instead of ==, but I would personally just rewrite it as !mailArray[i].
I'd recommend changing your output to be a markdown table for legability. Here's the code I ended up with:
var mailArray = #All of Email text with nulls
var nameArray = #All of Name with nulls
var temp = new Array()
var table = "Email | Contact \n --- | --- "
for (var i = 0; i < mailArray.length; i++) {
if (!mailArray[i].value){// !== null) {
temp.push("correct")
temp.push(mailArray[i])
table +="\n"+ mailArray[i] + " | " + nameArray[i]
}
else {
temp.push("null")
table +="\n"+ mailArray[i] + " | " + nameArray[i] + "\n"
temp.push(mailArray[i])
}
}
temp.join(" ")
write = table
And this outputs the following table (made 3 contacts, 2 with emails and one without):

Using List inside a postgres Query

i have a dynamic list.
list=['a','b','c','d' ..... ] so length may change
i want to compare these list values in a query
select * from student where name in(all the list values);
i want to pass list values into this query
how i can do this.. ??? please help
Thank you
In Postgres, you can use arrays. The syntax in the where clause looks like:
where name = any (array[1, 2, 3])
or
where name = any (list_parameter)
You can write a function that gets a list as a parameter and return a string like "'one', 'two','three'".
// need a string like this 'one', 'two'
private String arrayToSqlInChecker(List<String> loc_list) {
StringBuilder value = new StringBuilder("");
for (int i = 0; i < loc_list.size(); i++) {
value.append("'" + loc_list.get(i) + "'");
if (i != loc_list.size() - 1) {
value.append(",");
}
}
return value.toString();
}
And then you have to append this string into you PostgreSQL IN query
"id IN (" + this.arrayToSqlInChecker(loc_list) + ")"
You can also handle null or empty values in the function

SQLite with Android Studio, return all records selected by 2 arguments

let's assume that i have a table with columns such as:
ID SSID BSSID RSSI
1 abcd hs:hd:sd -60
2 abcd hs:hd:po -68
There are about 5000 records with the same SSID, slighltly different BSSID and the LEVEL values. My device is scanning the nearest environment for WiFi networks, therefore I know their MAC address and level of RSSI. I pick 3 with the highest value od RSSI.
First thing I would like to know if it is possible to search through the database to get all the records with the LEVEL value equal or close to 60, for instance 59,58,61.
Secondly, is there a way to query the database to return all the records with the same MAC addresses and RSSI values as from the 3 best scan result? If so, how would that query look like?
EDIT: Thanks for all the answers. What I'm trying to do now is to compare 3 scans with records stored in database with getRequiredData function. I would like to pass 2 parameters to this function, mac address and level and find records with same value for both parameters. The rawQuery seems to be fine, code is compiling but the app is crashing with the first scan. I cant find the cause of it, is it because my logic of getting these parameters is wrong or does it have something to do with query?
public Cursor getRequiredData(String mac, int level){
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("SELECT BSSID, RSSI FROM TABLE_NAME WHERE BSSID =? AND RSSI=?", new String[] {mac, level});
return res;
}
scan part:
class WifiReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
sb = new StringBuilder();
Comparator<ScanResult> comparator = new Comparator<ScanResult>() {
#Override
public int compare(ScanResult o1, ScanResult o2) {
return (o1.level>o2.level ? -1 : (o1.level==o2.level ? 0 : 1));
}
};
lista = wifiManager.getScanResults();
Collections.sort(lista, comparator);
for (int i = 0; i < lista.size(); i++) {
scanResult = wifiManager.getScanResults().get(i);
sb.append(new Integer(i + 1).toString() + ". " + (lista.get(i)).SSID + " " + (lista.get(i)).BSSID + " " + (lista.get(i)).level + "\n");
boolean isInserted = myDb.insertData(lista.get(i).SSID.toString(), lista.get(i).BSSID.toString(), lista.get(i).level);
if (isInserted = true)
Toast.makeText(MainActivity.this, "Data inserted", Toast.LENGTH_LONG).show();
else
Toast.makeText(MainActivity.this, "Data not inserted", Toast.LENGTH_LONG).show();
}
for (int i=0; i<4; i++)
{
scanResult = wifiManager.getScanResults().get(i);
match = myDb.getRequiredData(lista.get(i).BSSID.toString(), lista.get(i).level);
}
Log.i("match values: ", DatabaseUtils.dumpCursorToString(match));
txt.setText(sb);
wifiManager.startScan();
}
}
Here is what match contains:
2018-12-10 16:36:26.334 13347-13347/com.example.maciek.wifiscann I/match values:: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#e1a86d1
0 {
BSSID=f4:c5:ed:5c:s6:20
RSSI=-69
}
1 {
BSSID=f4:c5:ed:5c:s6:20
RSSI=-69
}
2 {
BSSID=f4:c5:ed:5c:s6:20
RSSI=-69
}
3 {
BSSID=f4:c5:ed:5c:s6:20
RSSI=-69
}
4 {
BSSID=f4:c5:ed:5c:s6:20
RSSI=-69
}
5 {
BSSID=f4:c5:ed:5c:s6:20
RSSI=-69
}
<<<<<
To get the 3 rows with the closest values to 60 in column LEVEL:
SELECT * FROM tablename ORDER BY ABS(LEVEL - 60), LEVEL LIMIT 3
For the 2nd part of your question, you should provide sample data of the table. Edit:
From the sample data that you posted I don't see a column RSSI, but if it exists in the table then the SELECT statement is ok.
Change the 2nd parameter of rawQuery() to:
new String[] {mac, String.valueOf(level)}
because level is int.
In onReceive() you use myDb. I don't know how you initialize it.
If the app crashes you must copy the log, the part that identifies the problem and post it.
First thing I would like to know if it is possible to search through
the database to get all the records with the LEVEL value equal or
close to 60, for instance 59,58,61.
SELECT * FROM your_table WHERE level BETWEEN 59 AND 61;
where your_table is the respective table name.
Note if levels are negative (as per example data) then BETWEEN requires the lowest value first so it would be BETWEEN -61 AND -59.
Secondly, is there a way to query the database to return all the
records with the same MAC addresses and RSSI values as from the 3 best
scan result? If so, how would that query look like?
SELECT * FROM your_table WHERE your_mac_address_column = 'the_mac_address_value' AND RSSI = 'the_rssi_value' ORDER BY LEVEL DESC LIMIT 3
Note the above assumes that the MAC address is stored in a column (if NOT then cannot be done unless the mac address can be correlated to a column).
Assumes best LEVEL is lowest so -1 is better than -60 (if not then use ASC instead of DESC)
Again your_table, your_mac_address_column, the_mac_address_value and the_rssi_value would be replaced accordingly with actual values (note that strings should be in single quotes).

Qliksense Extension - Select Values

I need to pass the value 'A' to be selected into a Qliksense extension. This extension contains 1 dimension and 1 measure. I would like 'A' to be selected in the 1 dimension.
It seems that self.selectValues(0, 'A', false); is the call for this. I can't get this to work at all.
How do I select 'A' in this extension or the underlying table?
Details:
I have the following code inside the paint function that renders the data (this part works):
// iterate over all rows
var hc = layout.qHyperCube;
for (var r = 0; r < hc.qDataPages[0].qMatrix.length; r++) {
table += '<tr>';
// iterate over all cells within a row
for (var c = 0; c < hc.qDataPages[0].qMatrix[r].length; c++) {
table += '<td>';
table += hc.qDataPages[0].qMatrix[r][c].qText;
table += '</td>';
}
table += '</tr>';
}
Method expects an array and the element number of the dimension value, so this should work:
self.selectValues(0, [qElemNumber], false);

How to group overlapping data in SQL

I have data in following fashion
Prog_Id Low_latency Max_Latency
a 1 4
a -1 5
a 3 8
a 11 12
a 12 15
Now I wish to see output as
Prog_Id Low_latency Max_Latency
a -1 8
a 11 15
Basically I wish to merge overlapping data. Can anyone help me with the code. I can manage time at the place of latency, if there is a solution with OVERLAPS clause.
Thanks
Rishabh
My initial answer was not always working. Now it looks like it is:
select distinct *
from (
select
t1.Prog_ID,
min(least(l, Low_latency)),
max(greatest(g, Max_Latency))
from yourtable t1 inner join (select
t1.Prog_ID,
least(t1.Low_latency, t2.Low_latency) l,
greatest(t1.Max_Latency, t2.Max_Latency) g
from
yourtable t1 inner join yourtable t2
on t1.Prog_ID=t2.Prog_ID
and t1.Low_latency<=t2.Max_Latency
and t1.Max_Latency>=t2.Low_Latency) t2
on t1.Prog_ID=t2.Prog_ID
and t1.Low_latency<=t2.g
and t1.Max_Latency>=t2.l
group by t1.Low_latency, t1.Max_latency) s
please see here. It's MySql code but can be converted for other DBMS.
It depends on which databse server (DBMS) you use. But there is no easy solution for. There could be a possibility to use Stored procedures . But I would prefer to do this in a programming language (which language do you use?)
After testing some around with querys of other people, I found no way in SQL.
Here is something simular to map reduce in java
public class YourData {
Double Low_latency;
Dobule Max_Latency;
int Prog_Id;
// add getter and setter here
public boolean tesetOverlapping(YourData data) {
if ((this.Low_latency<=data.Low_latency && data.Low_latency<=t1.Max_Latency) ¦¦ (this.Low_latency<=data.Max_Latency && data.Max_Latency<=this.Max_Latency)) {
this.Low_latency = Math.min(this.Low_latency, data.Low_latency);
this.Max_Latency = Math.min(this.Max_Latency, data.Max_Latency);
return true
}
return false;
}
}
String sql = "
SELECT
t1.Prog_Id,
t1.Low_latency,
t1.Max_Latency
FROM yourtable t1"
ArrayList<ArrayList<Double>> values = new ArrayList<ArrayList<Double>>();
while (row = get sql rows) {
int progIndex = values.indexOf(row.Prog_Id);
if (progIndex == -1) {
progIndex = values.indexOf(row.Prog_Id);
values.add(progIndex, new ArrayList<Double>());
}
values[progIndex].add(new YourData(row));
}
boolean foundOverlapping = false;
for (int progIndex = 0; progIndex < values.size(); progIndex++) {
// Do map reduce for each progIndex
do {
foundOverlapping = false;
for (int i = 0; i < values[progIndex].size(); i++) {
if (!values[progIndex].contains(i)) {
continue;
}
YourData cur = values[progIndex][i];
for (int x = 0; x < values[progIndex].size(); x++) {
if (i != x && values[progIndex].contains(x)) {
if (cur.tesetOverlapping(values[progIndex][x])) {
foundOverlapping = true;
values[progIndex].remove(x);
}
}
}
}
} while (foundOverlapping == true);
}
Assuming you want to group in a -infinity...9, 10...19, 20...29 pattern for the lower latency, you would need something like
SELECT
Prog_Id,
MIN(Low_latency) AS Low_latency,
MAX(Max_Latency) AS Max_Latency
FROM
your_table_name
GROUP BY
Prog_Id,
IF(FLOOR(Low_latency/10)<0,0,FLOOR(Low_latency/10))
Obviously the last line will depend on the RDBMS used, but should be quite similar among most.
You might also want to add an ORDER BY clause.