Concatenate columns in SQL query result from a single table - sql-server

I have query that looks something like the following:
select firstname, lastname
from names
where firstname = 'john'
I would like to have something like the following (conceptually):
select
[names.firstname + names.lastname] as 'fullname'
from names
where names.firstname = 'john'
Of course, this returns an invalid column name 'names.firstname + names.lastname'.
Is it possible to return a single aliased column containing the result of two columns from the same table?

Thanks for the comments; In this case it looks like the following will work as needed:
CONCAT(ISNULL(names.FirstName, '(No First Name)',
' ', ISNULL(names.LastName, '(No Last Name)')) AS 'FullName'

Related

Divide personal names in separate columns

I have one table which is called #MyNames.This table in one column contain full name of persons (Name space Surname). In this column we can distinct name from surname with space with them.From left side we have name and after space we have surname.Below you can see table:
So my intention is to divided this column with name MyFullName into two separate columns called ,,FirstName" and ,,LastName''. In order to do this i try with this code:
SELECT LEFT(MyFullName,charindex(' ', MyFullName) - 1) AS FirstName, RIGHT(MyFullName,charindex(' ', MyFullName)-1 ) AS LastName
from #MyNames
Output from this code is not good and I have results like table below :
So can anybody help me how to fix this code and get result correctly and to have fist name in one column and second name in other column?
Obviously the surname clause isn't working correctly.
Instead of using RIGHT(MyFullName,charindex(' ', MyFullName)-1 ) consider SUBSTRING(MyFullName,charindex(' ', MyFullName) + 1, 100) (or whatever field length is).
A better approach (though less easy to read imo) is to replace the first name component with blank '' characters.
STUFF(MyFullName,1,charindex(' ', MyFullName),'')
These should both work
SELECT LEFT(MyFullName,charindex(' ', MyFullName)-1) AS FirstName,
SUBSTRING(MyFullName,charindex(' ', MyFullName)+1, 100) AS LastName
from #MyNames
SELECT LEFT(MyFullName,charindex(' ', MyFullName)-1) AS FirstName,
STUFF(MyFullName,1,charindex(' ', MyFullName),'') AS LastName
from #MyNames
A small correction in your query should fix the problem.
SELECT LEFT(MyFullName,charindex(' ', MyFullName) - 1) AS FirstName
, RIGHT(MyFullName,len(MyFullName) - charindex(' ', MyFullName)) AS LastName
from #MyNames

How can I remove the first three characters of a column if they contain the word "to "?

I have a table where the column [English] sometimes has data that contains the word "to ".
How can I remove the "to " from the fields in just those rows that have it. So that for example:
to eat
would become
eat
One way is to use stuff:
SELECT CASE WHEN ColumnName LIKE 'to %' THEN
STUFF(ColumnName, 1, 3, '')
ELSE
ColumnName
END As ColumnName
FROM TableName
Another option is to use right with len:
SELECT CASE WHEN ColumnName LIKE 'to %' THEN
RIGHT(ColumnName, LEN(ColumnName) - 3)
ELSE
ColumnName
END As ColumnName
FROM TableName
I guess you are looking for something like this:
UPDATE TableName
SET ColumnName = SUBSTRING(ColumnName,4,len(ColumnName))
WHERE ColumnName LIKE 'to %';
Before and After image
select case when CHARINDEX('to',column,0) = 0 then column
else replace(column,'to ', '') end as column --there is one space after 'to '
FROM TABLE
WHERE --specify which rows here

PostgreSQL - join statement duplicate row data combine to single row [duplicate]

I am looking for a way to concatenate the strings of a field within a group by query. So for example, I have a table:
ID COMPANY_ID EMPLOYEE
1 1 Anna
2 1 Bill
3 2 Carol
4 2 Dave
and I wanted to group by company_id to get something like:
COMPANY_ID EMPLOYEE
1 Anna, Bill
2 Carol, Dave
There is a built-in function in mySQL to do this group_concat
PostgreSQL 9.0 or later:
Modern Postgres (since 2010) has the string_agg(expression, delimiter) function which will do exactly what the asker was looking for:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9 also added the ability to specify an ORDER BY clause in any aggregate expression; otherwise you have to order all your results or deal with an undefined order. So you can now write:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
PostgreSQL 8.4 (in 2009) introduced the aggregate function array_agg(expression) which collects the values in an array. Then array_to_string() can be used to give the desired result:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x and older:
When this question was originally posed, there was no built-in aggregate function to concatenate strings. The simplest custom implementation (suggested by Vajda Gabo in this mailing list post, among many others) is to use the built-in textcat function (which lies behind the || operator):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Here is the CREATE AGGREGATE documentation.
This simply glues all the strings together, with no separator. In order to get a ", " inserted in between them without having it at the end, you might want to make your own concatenation function and substitute it for the "textcat" above. Here is one I put together and tested on 8.3.12:
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
This version will output a comma even if the value in the row is null or empty, so you get output like this:
a, b, c, , e, , g
If you would prefer to remove extra commas to output this:
a, b, c, e, g
Then add an ELSIF check to the function like this:
CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSIF instr IS NULL OR instr = '' THEN
RETURN acc;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
How about using Postgres built-in array functions? At least on 8.4 this works out of the box:
SELECT company_id, array_to_string(array_agg(employee), ',')
FROM mytable
GROUP BY company_id;
As from PostgreSQL 9.0 you can use the aggregate function called string_agg. Your new SQL should look something like this: SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
I claim no credit for the answer because I found it after some searching:
What I didn't know is that PostgreSQL allows you to define your own aggregate functions with CREATE AGGREGATE
This post on the PostgreSQL list shows how trivial it is to create a function to do what's required:
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
SELECT company_id, textcat_all(employee || ', ')
FROM mytable
GROUP BY company_id;
As already mentioned, creating your own aggregate function is the right thing to do. Here is my concatenation aggregate function (you can find details in French):
CREATE OR REPLACE FUNCTION concat2(text, text) RETURNS text AS '
SELECT CASE WHEN $1 IS NULL OR $1 = \'\' THEN $2
WHEN $2 IS NULL OR $2 = \'\' THEN $1
ELSE $1 || \' / \' || $2
END;
'
LANGUAGE SQL;
CREATE AGGREGATE concatenate (
sfunc = concat2,
basetype = text,
stype = text,
initcond = ''
);
And then use it as:
SELECT company_id, concatenate(employee) AS employees FROM ...
This latest announcement list snippet might be of interest if you'll be upgrading to 8.4:
Until 8.4 comes out with a
super-effient native one, you can add
the array_accum() function in the
PostgreSQL documentation for rolling
up any column into an array, which can
then be used by application code, or
combined with array_to_string() to
format it as a list:
http://www.postgresql.org/docs/current/static/xaggr.html
I'd link to the 8.4 development docs but they don't seem to list this feature yet.
Following up on Kev's answer, using the Postgres docs:
First, create an array of the elements, then use the built-in array_to_string function.
CREATE AGGREGATE array_accum (anyelement)
(
sfunc = array_append,
stype = anyarray,
initcond = '{}'
);
select array_to_string(array_accum(name),'|') from table group by id;
Following yet again on the use of a custom aggregate function of string concatenation: you need to remember that the select statement will place rows in any order, so you will need to do a sub select in the from statement with an order by clause, and then an outer select with a group by clause to aggregate the strings, thus:
SELECT custom_aggregate(MY.special_strings)
FROM (SELECT special_strings, grouping_column
FROM a_table
ORDER BY ordering_column) MY
GROUP BY MY.grouping_column
Use STRING_AGG function for PostgreSQL and Google BigQuery SQL:
SELECT company_id, STRING_AGG(employee, ', ')
FROM employees
GROUP BY company_id;
I found this PostgreSQL documentation helpful: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html.
In my case, I sought plain SQL to concatenate a field with brackets around it, if the field is not empty.
select itemid,
CASE
itemdescription WHEN '' THEN itemname
ELSE itemname || ' (' || itemdescription || ')'
END
from items;
If you are on Amazon Redshift, where string_agg is not supported, try using listagg.
SELECT company_id, listagg(EMPLOYEE, ', ') as employees
FROM EMPLOYEE_table
GROUP BY company_id;
According to version PostgreSQL 9.0 and above you can use the aggregate function called string_agg. Your new SQL should look something like this:
SELECT company_id, string_agg(employee, ', ')
FROM mytable GROUP BY company_id;
You can also use format function. Which can also implicitly take care of type conversion of text, int, etc by itself.
create or replace function concat_return_row_count(tbl_name text, column_name text, value int)
returns integer as $row_count$
declare
total integer;
begin
EXECUTE format('select count(*) from %s WHERE %s = %s', tbl_name, column_name, value) INTO total;
return total;
end;
$row_count$ language plpgsql;
postgres=# select concat_return_row_count('tbl_name','column_name',2); --2 is the value
I'm using Jetbrains Rider and it was a hassle copying the results from above examples to re-execute because it seemed to wrap it all in JSON. This joins them into a single statement that was easier to run
select string_agg('drop table if exists "' || tablename || '" cascade', ';')
from pg_tables where schemaname != $$pg_catalog$$ and tableName like $$rm_%$$

A table has two columns - how we can get the full_name into one column?

I am following sample data in SQL Table:-
First_Name Last_Name Concatenation(F_Name,L_Name)
-------------------------------------------------------------
Mohd Nazir Mohd,Nazir
I want to see the result as
Full_Name = Mohd Nazir
within the same table
How about
ALTER TABLE dbo.YourTableNameHere
ADD FullName AS ISNULL(First_Name, '') + ' ' + ISNULL(Last_Name, '')
With this computed column, you have a new column in your table that'll always contain the concatenation of first and last name, separated by a space

Query a database from a search with empty values

I am using asp .net web form search in c#, for example with fields:
- name
- fruit
I want to write a sproc that can search name or fruit. If I knew that both would have values, I would pass two parameters into the sproc and would write:
Select * from myTable where name =#name and fruit = #fruit
However sometimes, either name or fruit could be empty. Without writing a separate search for fruit and name. How would I achieve this?
I would prefer not to create a dynamic query if possible, but if this is the only way how would I write it?
You'll need to make sure that empty strings aren't passed as arguments instead of null, but the following should work. I'm pretty sure, though, that if the user doesn't input anything the form value will be null.
select * from myTable
where (#name is null or name = #name) and (#fruit is null or fruit = #fruit)
maybe:
SELECT * FROM myTable WHERE name Like '%' + #name AND fruit LIKE '%' + #fruit
select * from myTable
where
(name = #name and fruit = #fruit)
or (name = #name and #fruit is null)
or (fruit = #fruit and #name = is null )
select * from myTable where name = isnull(#name, name) and fruit = isnull(#fruit, fruit)
Will return the entire table if both #name and #fruit is null. If that is a problem, you better add some additional logic to the SP.

Resources