SQL Result to multiple array - sql

MY SQL returns the following array...
id
staff
province
1
Ben
Ontario
2
Ben
Quebec
3
John
Manitoba
4
John
Saskatchewan
6
Kitty
Alberta
7
Kitty
Nova Scotia
I would like to have the record displayed like this...
staff
province
Ben
Ontario, Quebec
John
Quebec, Manitoba, Saskatchewan
Kitty
Alberta, Nova Scotia
what approach should I use to approach this?

Would be better to post the tables as well for clearer context.
You can use Aggregate functions and Grouping to help doing this. A GROUP BY to group the rows by staff column, then use GROUP_CONCAT() to concatenate province values in one string.
A reference of how you want it to be, unsure what table you are using or if there are any other factors but you can adapt as needed.
SELECT staff, GROUP_CONCAT(province SEPARATOR ', ') as province
FROM table_name
GROUP BY staff;

Related

Grouping values and changing values which do not allow the rest of the row to group

Not sure how to describe this, but I want to group a row of values, where one field has two or more different values and set the value of that (but concatenating or changing the values) to give just one single row.
For example:
I have a simple table (all fields are Strings) of people next to their departments. But some people belong to more than one department.
select department_ind, name
from jobs
;
department_ind name
1 Michael
2 Michael
2 Sarah
3 Dave
2 Sally
4 Sally
I want to group by name, and concatenate the department_ind. So the results show look like:
department_ind name
1,2 Michael
2 Sarah
3 Dave
2,4 Sally
Thanks
Use string_agg()
select string_agg(department_ind::text, ',') as departments,
name
from jobs
group by name;

Compute number of direct report for each employee in the organization (aggregation)

FYI I use Redshift SQL.
I have a database that looks roughly like the one below (the database has multiple columns that I'll abstract away for simplicity).
This table is a representation of the hierarchical tree within my organization.
employee manager
-------- -------
daniel louis
matt martha
martha kim
laura matt
michael martha
...
As you can see, matt appears in two distinct records, one as the employee and the other as laura's manager. Martha appears in three records, one as an employee and in two other as manager.
I'd like to find a way to compute the number of direct reports each employee has. A conditional count in which the criteria would be where employee = manager, perhaps?
I guess I could find this information using a subquery and then join it back but I was wondering if there was a more "elegant" way to do this making use of window functions maybe.
The expected output for the table above would be:
employee manager direct_reports
-------- ------- --------------
daniel louis 0
matt martha 1
martha kim 2
laura matt 0
michael martha 0
...
I would approach this with a correlated subquery:
select
t.employee,
t.manager,
(select count(*) from mytable t1 where t1.manager = t.employee) direct_reports
from mytable t
This should be a quite efficient method, especially with an index on (employee, manager).
Use a left join and aggregation:
select em.employee, em.manager, count(ew.employee)
from employees em left join
employees ew
on ew.manager = em.employee
group by em.employee, em.manager;

Count number of rows that have a specific word in a varchar (in postgresql)

I have a table similar to the below:
id | name | direction |
--------------------------------------
1 Jhon Washington, DC
2 Diego Miami, Florida
3 Michael Orlando, Florida
4 Jenny Olympia, washington
5 Joe Austin, Texas
6 Barack Denver, Colorado
and I want to count how many people live in a specific state:
Washington 2
Florida 2
Texas 1
Colorado 1
How can I do this? (By the way this is just an question with an academic point of view )
Thanks in advance!
Postgres offers the function split_part(), which will break up a string by a delimiter. You want the second part (the part after the comma):
select split_part(direction, ', ', 2) as state, count(*)
from t
group by split_part(direction, ', ', 2);
Initially I would obtain the state from the direction field. Once you have that, it's quite simple:
SELECT state, count(*) as total FROM initial_table group by state.
To obtain the state, some functions depending on the dbms are useful. It depends on the language.
A possible pseudocode (given a function like substring_index of MySQL) for the query would be:
SELECT substring_index(direction,',',-1) as state, count(*) as total
FROM initial_table group by substring_index(direction,',',-1)
Edit: As it is suggested above, the query should return 1 for the Washington state.
My way do making such a queries is two-step - first, prepare fields you need, second, do you grouping or other calculation. That way you're following DRY principle and don't repeating yourself. I think CTE is the best tool for this:
with cte as (
-- we don't need other fields, only state
select
split_part(direction, ', ', 2) as state
from table1
)
select state, count(*)
from cte
group by state
sql fiddle demo
If you writing queries that way, it's easy to change grouping field in the future.
Hope that helps, and remember - readability counts! :)

The best way to get counts of occurrences

I have the following data structure :
FIRSTNAME AGE NICKNAME
Jack 28 Benny
Robert 30 Benny
Pascal 20 Benny
Charles 19 Lence
Anthony 20 Lence
The first column is unique.
The idea is that I have to count how many times the "nickname" is used and I want to output it so that I can I have the following result :
Benny 3
Lence 2
What is the best performant way to do so knowing that I have millions of lines?
Try this:
SELECT NICKNAME,COUNT(NICKNAME)
FROM MyTable
GROUP BY NICKNAME
SELECT NICKNAME, SUM(1) FROM table GROUP BY NICKNAME
agregate count group by firstname, there's no other solution.
by the way, the benny nickname only appears 3 times, not 4.

VBA Access SQL - field within LIKE operator

Can I use a table column within a Like operator? I've created an example,
TableA
Names Location
Albert Smith Senior Aberdeen
John Lee London
Michael Rogers Junior Newcastle
Mary Roberts Edinburgh
TableB
Names
Albert Smith
John Lee
Michael Rogers
I want to do a query such as:
SELECT TableA.Location
into NewTable
FROM TableA
WHERE TableA.Names Like '*[TableB.Names]*';
In this case, there would be no match for Mary Roberts, Edinburgh but the first three locations would be returned.
Is it possible to put a column into a like statement?
If not does anyone have any ideas how I could do this?
Hope you can help
PS I can't use an actual asterisk since this is removed and the text italicised, also I have read about using % instead but this has not worked for me.
You can join the two tables and use LIKE within the JOIN clause:
SELECT TableA.Location
into NewTable
FROM TableA
INNER JOIN TableB ON TableA.Names LIKE TableB.Names & '*';
Honestly, I had no idea that you can do this in Access before I tried it just now :-)