Snowflake MERGE with columns that have spaces in their names - merge

I'm using Snowflake and have a table that has columns with spaces in their names. The code to create the table is:
create or replace MYTABLE (
"string 1" VARCHAR,
"number 1" NUMBER(38,0)
);
I want to now MERGE some data into the table using the following code:
merge into mytable using (
select * from
(
values('a', 4),('b', 5)
)
) as T ("string 1", "number 1") on FALSE
when not matched then
insert
("string 1", "number 1")
values
('string 1', 'number 1');
When I run the above, I get the following error:
Numeric value 'number 1' is not recognized
I've tried all manners of wrapping the column names in single quotes, double quotes, and $$ all to no avail. Suggestions?

Column could be referenced as T."""string 1""":
merge into mytable
using (
select * from
(
values('a', 4),('b', 5)
)
) as T ("string 1", "number 1") on FALSE
when not matched then
insert
("string 1", "number 1")
values
(T."""string 1""", T."""number 1""");
Output:
Rationale:
select *
from (values('a', 4),('b', 5)
) as T ("string 1", "number 1");
DESCRIBE RESULT LAST_QUERY_ID();
-- name
-- "string 1"
-- "number 1"
" is part of the column name "string 1" therefore when referencing """string 1"""

Related

ERROR: UNION types integer and character varying cannot be matched [SQL State=42804]

I am doing union of two views but getting above error. Please help me to resolve this issue.
some values are hardcoded there and need to extract the same in final view.
I am using below query in redshift-
query:
DROP VIEW IF EXISTS jgbl.vw_jgvcc_crm_case_activity CASCADE;
CREATE OR REPLACE VIEW jgbl.vw_jgvcc_crm_case_activity
AS
SELECT case_number as "CASE Number",
parent_case_number as "Parent Case Number",
date_opened as "Date Opened",
number_of_questions as "Number of Questions",
case_record_type as "CASE Record Type",
NULL as "Sub Type",
category as "Category",
NULL as "Sub Category",
country as Country,
customer_type as "Customer Type",
primary_account_subtype as "Primary Account Subtype",
source as Source,
call_center_location as "Call Center Location",
region as Region,
customer_region as "Customer Region",
NULL as "AE",
NULL as "PQC",
'ASPAC' as datasource
FROM JG_ASPAC.vw_jgvcc_aspac_crm_activity
UNION ALL
SELECT case_num as "CASE Number",
NULL as "Parent Case Number",
open_dt as "Date Opened",
cast(num_of_ques as integer) as "Number of Questions",
rec_type_nm as "CASE Record Type",
rec_sub_type as "Sub Type",
cat_desc as "Category",
sctgy_desc as "Sub Category",
custm_latam_ctry_nm as Country,
acct_type as "Customer Type",
NULL as "Primary Account Subtype",
src_in as Source,
case when alph_fl='Y' then 'Alphanumeric' else 'LATAM Center' end as "Call Center Location",
'LATAM' as Region,
NULL as "Customer Region",
Case when rec_type_nm='AE/PQC' and rec_sub_type in ('ADVERSE EVENT','AE + PQC') then 'Y' else 'N' End as "AE",
Case when rec_type_nm='AE/PQC' and rec_sub_type in ('AE + PQC', 'PRODUCT QUALITY COMPLAINT') then 'Y' else 'N' End as "PQC",
'LATAM' as datasource
FROM JG_LTM.vw_jgvcc_latam_crm_activity as v2
--LEFT JOIN jgbl.dim_iso_reg_cntry as t1 on t1.region = v2.ctry_iso2_cd
with no schema binding;
error:
An error occurred when executing the SQL command:
select * from jgbl.vw_jgvcc_crm_case_activity limit 10
ERROR: Invalid digit, Value '.', Pos 1, Type: Integer
Detail:
error: Invalid digit, Value '.', Pos 1, Type: Integer
code: 1207
context: 1.0
query: 87576
location: :0
process: query1_562_87576 [pid=0]
----------------------------------------------- [SQL State=XX000]
1 statement failed.
Execution time: 4.81s

SPLIT() then JOIN() and populate column with ARRAYFORMULA()

I am trying to Split email addresses in column E2:E on the "dot" operator and then Join the names back into a single cell. I have written the below formula enclosed with ARRAYFORMULA() to populate the cells in Column A. But i keep getting the following error:
JOIN range must be a single row or a single column.
=ARRAYFORMULA( IF( E2:E = "", "", JOIN( " ", SPLIT( SUBSTITUTE( FILTER( E2:E, LEN( E2:E ) > 0 ), "#abc.com", "", 1 ), ".") ) ) )
Is there a workaround solution?
I think i found the answer:
=ARRAYFORMULA(IF(E2:E="","",TRANSPOSE(QUERY(TRANSPOSE(SPLIT(SUBSTITUTE(FILTER(E2:E,LEN(E2:E)>0),"#ABC.COM","",1),".")),,50000))))

Split column into columns using split_part returning empty

I have a column stored as text in postgres 9.6. It's an address and some of the rows have format like BUILD NAME, 40
I saw this answer which looks like what i want, if i run;
select split_part('BUILD NAME, 40', ',', 2) as address_bldgno
It returns; 40 as I want.
When i try;
select
split_part(address, ', ', 1) as address_bldgname,
split_part(address, ', ', 2) as address_bldgno
from table;
It runs but returns empty values
As you mentioned:
...some of the rows have format...
I suspect anything that doesn't contain comma returns empty values.
That is due to the split_part condition does not find a match for the argument.
To illustrate how different address values are split here's some example:
WITH "table" ( address ) AS (
VALUES
( 'BUILD NAME, 40' ), -- first and second have value
( 'BUILD NAME' ), -- only first have value (bldgname)
( '40' ), -- only first have value (bldgname)
( ', 40' ), -- first is empty string, second is value
( 'BUILD NAME,' ), -- first is value, second is empty string
( NULL ), -- both are NULL
( '' ) -- no match found, both are empty strings
)
SELECT split_part( address, ', ', 1 ) as address_bldgname,
split_part( address, ', ', 2 ) as address_bldgno
FROM "table";
-- This is how it looks in result:
address_bldgname | address_bldgno
------------------+----------------
BUILD NAME | 40
BUILD NAME |
40 |
| 40
BUILD NAME, |
|
|
(7 rows)
If you want to set some defaults for NULL and empty string I recommend to read also: this answer
Answer found here;
PostgreSQL 9.3: Split one column into multiple
Should have been;
select somecol
,split_part(address, ', ', 1) as address_bldgname
,split_part(address, ', ', 2) as address_bldgno
from table;
By adding another column to the select I get all the values of that column back, and the split_part() results where they exist.

Invalid length parameter passed to the LEFT or SUBSTRING function

I have the following description: 'Sample Product Maker Product Name XYZ - Size' and I would like to only get the value 'Product Name XYZ' from this. If this were just one row I'd have no issue just using SUBSTRING but I have thousands of records and although the initial value Sample Product Maker is the same for all products the Product Name could be different and I don't want anything after the hyphen.
What I have so far has generated the error in the header of this question.
SELECT i.Itemid,
RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 25, (SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)))))) AS ProductDescriptionAbbrev,
CHARINDEX('-', i.ShortDescription, 0) - 25 as charindexpos
FROM t_items i
I am getting 'Argument data type varchar is invalid for argument 3 of substring function'
As you can see, I am getting the value for the last line the sql statement but when I try and plug that into the SUBSTRING function I get various issues.
Chances are good you have rows where the '-' is missing, which is causing your error.
Try this...
SELECT i.Itemid,
SUBSTRING(i.ShortDescription, 22, CHARINDEX('-', i.ShortDescription+'-', 22)) AS ProductDescriptionAbbrev,
FROM t_items i
You could also strip out the Sample Product Maker text and go from there:
SELECT RTRIM(LEFT(
LTRIM(REPLACE(i.ShortDescription, 'Sample Product Maker', '')),
CHARINDEX('-', LTRIM(REPLACE(i.ShortDescription, 'Sample Product Maker',
'' ))) - 1))
AS ShortDescription
Your first call to SUBSTRING specifies a length of SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)).
You might try:
declare #t_items as Table ( ItemId Int Identity, ShortDescription VarChar(100) )
insert into #t_items ( ShortDescription ) values
( 'Sample Product Maker Product Name XYZ - Size' )
declare #SkipLength as Int = Len( 'Sample Product Maker' )
select ItemId,
RTrim( LTrim( Substring( ShortDescription, #SkipLength + 1, CharIndex( '-', ShortDescription, #SkipLength ) - #SkipLength - 1 ) ) ) as ProductDescriptionAbbrev
from #t_items
The problem is that your outer call to SUBSTRING is being passed a character data type from the inner SUBSTRING call in the third parameter.
+--This call does not return an integer type
SELECT i.Itemid, V
RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 25, (SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)))))) AS ProductDescriptionAbbrev,
CHARINDEX('-', i.ShortDescription, 0) - 25 as charindexpos
FROM t_items i
The third parameter must evaluate to the length that you want. Perhaps you meant LEN(SUBSTRING(...))?
Seems like you want something like this (22, not 25):
SELECT i.Itemid,
RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 22, CHARINDEX('-', i.ShortDescription)-22))) AS ProductDescriptionAbbrev,
CHARINDEX('-', i.ShortDescription)-22 as charindexpos
FROM t_items i
You want:
LEFT(i.ShortDescription, isnull(nullif(CHARINDEX('-', i.ShortDescription),0) - 1, 8000))
Note that a good practice is to wrap charindex(...)'s and patindex(...)'s with nullif(...,0), and then handle the null case if desired (sometimes null is the right result, in this case we want all the text so we isnull(...,8000) for the length we want).

Report Builder .rdl Check Array Key Exists

I am making a report and I need to split a coma separated string into three columns of a table.
string = 'some text, some text, some text'
But the sting doesn't always have two coma's i.e.
string = 'some text, some text'
so when i try to get the value for the third column
=Split(Fields!GLDescription.Value, ", ").GetValue(2)
This code can result in a "#Error" message in the column. I tried to solve this by checking the length like so
=IIF(Split(Fields!GLDescription.Value, ", ").Length >= 3, Split(Fields!GLDescription.Value, ", ").GetValue(2), "")
But it still resulted in the same error. Is there anyway to check if an array key exists?
The issue, as you've seen, is that SSRS IIf expressions aren't good at short circuiting. I can think of a workaround that will work for 2 and 3 column fields.
Try an expression like:
=IIf(
Split(Fields!GLDescription.Value, ", ").Length = 3
, Mid(
Fields!GLDescription.Value
, InStrRev(Fields!GLDescription.Value, ", ") + 2
, Len(Fields!GLDescription.Value) - InStrRev(Fields!GLDescription.Value, ", ") + 2
)
, "No val 3"
)
With dataset:
Gives result:
It's not bulletproof for all possible situations, but might be enough for your data.