How to join attributes in sql select statement? - sql

I want to join few attributes in select statement as one for example
select id, (name + ' ' + surname + ' ' + age) as info from users
this doesn't work, how to do it?
I'm using postgreSQL.

Postgres uses || to concatenate strings; your query needs to be:
select id, (name || ' ' || surname || ' ' || age) as info from users
It should be the key just above the Enter key on a full keyboard, but on mine it's not a sold line - there's a break in the middle of it. You have to hold the Shift key to get the character (called a pipe, btw).

I believe the ANSI standard concatenation operator is: ||
SELECT id, name ||' ' || surname || ' ' || age AS info FROM users

It perfectly might be dependent of the database I would take a look for a concatenation function for the database you are running the select for.
Example. Mysql: CONCAT(name, surname, age).

You may need to cast the fields to a common type before concatenating. In T-SQL for example this would read.
Select id, Cast(name as varchar(50)) + ' ' + Cast(surname as varchar(50)) + ' ' +
Cast(age as varchar(3)) As info From Users

|| is used for this purpose.
Use it like
select name ||' ' ||surname ||' ' ||age as info from users

If you're using mysql or oracle then try CONCAT function:
SELECT id, CONCAT(name, ' ', surname, ' ', age) as info FROM users

That should work as is, but in general it is better not to do too much concatenation sql side if you can help it; rather return all the columns and concat them on the other end.
What are the data types you are using? You may need to CAST / CONVERT into (n)varchar

Make sure your data types are similar and convert any datatypes to string as necessary:
select id, (name + ' ' + surname + ' ' + convert(varchar(3),age)) as info from users

Works fine in most databases I know, although you probably have to CAST the age field to be TEXT. The exact method for doing this depends on the database you're using, which you did not specify.

Related

How to pivot in bigQuery using PIVOT?

I am trying to pull rows as columns in bigquery.
This is how my data looks like now:
This is how I want my data to look like:
PS: While I have shown only 3 values in column SUB_CLASS_DESC actual count is in 100s. Hence, I am looking to use Procedural language as per documentation here. I followed the example shared here in towardsdatascience.com and wrote below code, but unfortunately that doesn't work:
DECLARE DEPT_CLASS_SUB_CLASS STRING;
SET DEPT_CLASS_SUB_CLASS = (SELECT CONCAT('("', STRING_AGG(DISTINCT DEPT_CLASS_SUB_CLASS, '", "'), '")')
FROM `analytics-mkt-cleanroom.Workspace.HS_AF_SG_R12_800K_SAMPLE_SALES_11_TEST`
);
EXECUTE IMMEDIATE FORMAT("""
CREATE OR REPLACE TABLE `analytics-mkt-cleanroom.Workspace.HS_AF_SG_R12_800K_SAMPLE_SALES_PIVOTED_12_TEST` AS
SELECT * FROM
(SELECT HH_ID,DEPT_CLASS_SUB_CLASS,SALE_AMT
FROM `analytics-mkt-cleanroom.Workspace.HS_AF_SG_R12_800K_SAMPLE_SALES_11_TEST`
)
PIVOT
(SUM(SALE_AMT)
,FOR DEPT_CLASS_SUB_CLASS IN %s
)""",DEPT_CLASS_SUB_CLASS);
Error I am getting:
Error message suggests to declare before the execute block, and I am doing exactly that, but I don't understand why the error still persists.
I tried declaring variables DEPT_CLASS_SUB_CLASS in different ways but not successful yet. Could anyone please point out where I might be making the mistake.
Much appreciated!
Consider below approach
execute immediate (select '''
select *
from your_table
pivot (any_value(sale_amt) for replace(sub_class_desc, ' ', '_') in (''' || list || '''))
'''
from (
select string_agg(distinct "'" || replace(sub_class_desc, ' ', '_') || "'") list
from your_table
)
)
if applied to dummy data as in your question - output is
How can I save these results into a new pivoted table? Specifically where can I put my CREATE OR REPLACE TABLE?
execute immediate (select '''
create or replace table `your_project.your_dataset.pivot_table` as
select *
from your_table
pivot (any_value(sale_amt) for replace(sub_class_desc, ' ', '_') in (''' || list || '''))
'''
from (
select string_agg(distinct "'" || replace(sub_class_desc, ' ', '_') || "'") list
from your_table
)
);
DEPT_CLASS_SUB_CLASS variable should be placed before any other statement, not just before an execute block being referenced.
From your error message, you seems to declare a variable at [411:1] which means at 411 line. Kindly move it to the top of your script at line 1 and test it again.
you have kind of a PIVOTing problem. I wrote down some test query which do PIVOTing and list columns in an alphabetical order at the same time.
DECLARE sample_data ARRAY<STRUCT<HH_ID STRING, SUB_CLASS_DESC STRING, SALE_AMT FLOAT64>> DEFAULT [
('HHH_001', 'K&B FIXTURE/PLUMBING', 139.),
('HHH_001', 'PULLDOWN KITCHEN FAUCETS', 129.),
('HHH_001', 'TUBULAR REPAIR & REPLACE', 0.)
];
CREATE TEMP TABLE data AS
SELECT r.* REPLACE(TRANSLATE(SUB_CLASS_DESC, ' &/', '___') AS SUB_CLASS_DESC)
FROM UNNEST(sample_data) r
;
EXECUTE IMMEDIATE FORMAT ("""
SELECT *
FROM data
PIVOT (SUM(SALE_AMT) AS sale_amt FOR SUB_CLASS_DESC IN ('%s'));
""", (SELECT STRING_AGG(DISTINCT SUB_CLASS_DESC, "','" ORDER BY SUB_CLASS_DESC ASC) FROM data)
);
Query Result

Trying to separate a FULL_NAME into FIRST_NAME and LAST_NAME in Oracle SQL, but it does not show any changes on the table itself

This code is supposed to separate full name and it does. This code works fine, except for the fact that it does not add the data to the table.
SELECT FULL_NAME
SUBSTR(FULL_NAME, 1, INSTR(FULL_NAME, ' ', 1, 1)-1) as FIRST_NAME,
SUBSTR(FULL_NAME, INSTR(FULL_NAME, ' ', -1)+1) as LAST_NAME
from customers;
This code runs similarly but again, does not populate the table.
ALTER TABLE CUSTOMERS;
SELECT
substr("A1"."FULL_NAME", 1, instr("A1"."FULL_NAME", ' ', 1, 1) - 1) "FIRST_NAME",
substr("A1"."FULL_NAME", instr("A1"."FULL_NAME", ' ',(- 1)) + 1) "LAST_NAME"
FROM
"XXXX"."CUSTOMERS" "A1";
This is what my query result is, it shows that everything is how it should be.
This is what my table looks like but as you can see, the last two columns do not have any data.
My goal is to be able to drop the FULL_NAME column, but I need these two split first and I am not sure why it is not working. Any help is appreciated.
A SELECT statement only displays data. It does not change it. ALTER TABLE is a DDL command that would actually change the structure of the table (like add a column), but you have not told it what to do; it does not change data. Use UPDATE to change data values:
UPDATE CUSTOMERS SET
FIRST_NAME = SUBSTR(FULL_NAME, 1, INSTR(FULL_NAME, ' ', 1, 1)-1),
LAST_NAME = SUBSTR(FULL_NAME, INSTR(FULL_NAME, ' ', -1)+1);
COMMIT;
You can use generated columns:
ALTER TABLE CUSTOMERS
ADD FIRST_NAME AS substr("FULL_NAME", 1, instr("FULL_NAME", ' ', 1, 1) - 1);
ALTER TABLE CUSTOMERS
ADD LAST_NAME AS substr("FULL_NAME", instr("FULL_NAME", ' ',(- 1)) + 1) ;
These are calculated when they are references so the values are always up-to-date. No UPDATE is needed.
Note: I strongly, strongly discourage you from using double quotes for column names. There is no need for them.
Here is a db<>fiddle.

Concatenating first, middle and last names in SQL when some people don't have middle names

I'm trying to return a concatenation of first, middle, and last name columns in a database table Authors. However some Authors just have NULL as a value in the middle name column.
As a result, my code below, for Authors with only a first and last name, returns the first name, followed by two spaces, followed by the last name.
I'd like to avoid this, and only ever have 1 space between each name, regardless of whether they have a middle name or not.
Is there a simple way of achieving this that I'm missing?
SELECT
CONCAT(FirstName, ' ', MiddleName, ' ', Lastname)
FROM Authors
EDIT:
I did find this, which involves RTRIM and COALESCE. Not sure if there's a simpler solution or if this is the best way:
How to combine first name, middle name and last name in SQL server
If you are using SQL Server and assuming your middle names cannot be empty, then you can do the following:
SELECT
CONCAT(FirstName, ISNULL(' '+ MiddleName + ' ', ' '), Lastname)
FROM Authors
Use CONCAT_WS:
CONCAT_WS(' ',FirstName, MiddleName, LastName)
Otherwise, if you're on an old(er) version of SQL Server, use STUFF remove the first delimiter:
STUFF(CONCAT(' ' + FirstName, ' ' + MiddleName, ' ' + LastName),1,1,'')
Try this:
select concat(FirstName, case when MiddleName is not null then concat(' ', MiddleName) else null end, concat(' ', LastName))
from Authors;
Based on your question I am assuming that all the authors have FirstName and LastName.
So, you can write your query using case.
SELECT
CASE
WHEN (ISNULL(MiddleName, '') <> '') THEN CONCAT(FirsName, ' ', MiddleName, ' ', Lastame)
ELSE CONCAT(FirsName, ' ', Lastame)
END AS FullName
FROM Authors
ISNULL is a function which will check if your value is null or empty.

ORA-00918: Column ambiguously defined (Oracle)

I need to select a column as ' ' (empty).
Here is my query:
SELECT NAME, ' ', ' '
FROM TABLE_NAME
GROUP BY NAME
While executing at the database level query there is no problem, but at the code level I am getting Column ambiguously defined Error.
Note From suggestions, that error is because of ' '. So, I wanted to follow
SELECT NAME, ' ' AS EMPTY1, ' ' AS EMPTY2
FROM TABLE_NAME
GROUP BY NAME
How long it's correct or any alternatives, please?
Your solution is correct.
alternative:
SELECT distinct NAME,
' ' AS EMPTY1,
' ' AS EMPTY2
FROM TABLE_NAME

Add keyword before and after cast() in oracle

I would like to add a keyword before and after each field value in Oracle.
For example if I am getting 123 as my ID, I would like to make it
Test123Test
Here is my query:
SELECT
CAST("ID" as varchar(10))
FROM
TABLENAME;
I have tried add + "Test" but it is giving me error.
Use || instead of + to concatenate strings in Oracle.
SELECT 'test' || CAST(ID as varchar(10)) || 'test'
FROM TABLENAME
Note that I removed the " around ID too, since you most likely won't need them and they can cause problems when it unintended strictly matches column names.
I have tried add + "Test" but it is giving me error.
Perhaps, + is used as concatenation in SQL Server. In Oracle, you could use the CONCAT function or the || operator.
The concat function is restricted to only two strings. You can have a look the concat function in the documentation http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions026.htm.
Let's see an example using the operator -
SELECT 'test' || to_char(id) || 'test' new_id
FROM TABLENAME