Is it possible in sql to group by fields matching some pattern? - sql

Is it possible in SQL to do grouping by LIKE patterns? I would like to achieve something like this:
id|name
1 | Mike
2 | Bob
3 | Bill
4 | Alice
and then doing query like: SELECT name from users group by _pattern_
For example I would like to get groups by matching patterns 'B*', '*l*' and 'Mike'
would give the output:
B* | Bob
| Bill
*l* | Bill
| Alice
Mike| Mike

Select 'B*' as Mask, Name
from Table
WHERE Name like 'B%'
UNION ALL
Select '*l*' as Mask, Name
from Table
WHERE Name like '%l%'
UNION ALL
Select 'Mike' as Mask, Name
from Table
WHERE Name like 'Mike'

If you want the same record to appear multiple times according to the pattern it matches, you should use multiple SELECT statements with the relevant filters and UNION them together..

You can query against the patterns in a set structure then GROUP BY or DISTINCT to remove dups, below is a way with an MSSQL CTE (temp table/table var would work also);
with match (pattern) as (
select 'B%'
union select '%l%'
union select 'Mike'
)
select
pattern,
name
from TABLE, match where TABLE.name like match.pattern
group by pattern, name
==
%l% Alice
%l% Bill
B% Bill
B% Bob
Mike Mike

Related

Rows which do not exist in a table

I have a lists of names John, Rupert, Cassandra, Amy, and I want to get names which are not exists in table: Cassandra, Amy
How should I write such query?
My table:
+----+--------+-----------+------+
| id | name | address | tele |
+----+--------+-----------+------+
| 1 | Rupert | Somewhere | 022 |
| 2 | John | Doe | 029 |
| 3 | Donald | Armstrong | 021 |
| 4 | Bob | Gates | 022 |
+----+--------+-----------+------+
Think in sets. You add names to a the result set with UNION ALL, you remove names from the result set with EXCEPT.
select 'John'
union all
select 'Rupert'
union all
select 'Cassandra'
union all
select 'Amy'
except
select name from mytable;
Build up a list of your names to check and do a left join to the users table:
with to_check (name) as (
values
('John'), ('Rupert'), ('Cassandra'), ('Amy')
)
select tc.name as missing_name
from to_check tc
left join the_table tt on tt.name = tc.name
where tt.name is null;
SQLFiddle example: http://sqlfiddle.com/#!15/5c4f5/1
Hope your list is in form of table lets its be table b and your original table as a
now SQL query goes like it
Select name from a where name not in (select name from b);
Think this will give you solution as per my understanding. Also if further details are required please comment.
Also its more important to search for an answer as it look like its a question from a book/Class. Please try out to find solution could have got much more information like link below
How to write "not in ()" sql query using join

SQL - Group by Elements of Comma Delineation

How can I group by a comma delineated list within a row?
Situation:
I have a view that shows me information on support tickets. Each ticket is assigned to an indefinite number of resources. It might have one name in the resource list, it might have 5.
I would like to aggregate by individual names, so:
| Ticket ID | resource list
+-----------+----------
| 1 | Smith, Fred, Joe
| 2 | Fred
| 3 | Smith, Joe
| 4 | Joe, Fred
Would become:
| Name | # of Tickets
+-----------+----------
| Fred | 3
| Smith | 2
| Joe | 3
I did not design the database, so I am stuck with this awkward resource list column.
I've tried something like this:
SELECT DISTINCT resource_list
, Count(*) AS '# of Tickets'
FROM IEG.vServiceIEG
GROUP BY resource_list
ORDER BY '# of Tickets' DESC
...which gives me ticket counts based on particular combinations, but I'm having trouble getting this one step further to separate that out.
I also have access to a list of these individual names that I could do a join from, but I'm not sure how I would make that work. Previously in reports, I've used WHERE resource_list LIKE '%' + #tech + '%', but I'm not sure how I would iterate through this for all names.
EDIT:
This is my final query that gave me the information I was looking for:
select b.Item, Count(*) AS 'Ticket Count'
from IEG.vServiceIEG a
cross apply (Select * from dbo.Split(REPLACE(a.resource_list, ' ', ''),',')) b
Group by b.Item
order by 2 desc
Check this Post (Function Definition by Romil) for splitting strings into a table:
How to split string and insert values into table in SQL Server
Use it this way :
select b.Item, Count(*) from IEG.vServiceIEG a
cross apply (
Select * from dbo.Split (a.resource_list,',')
) b
Group by b.Item
order by 2 desc

Search from comma separated values in column

I have a table with 2 columns - id and pets.
Pets column contain abbreviated pet names separated by , [comma] as shown below
+----+-------------+
| id | pets |
+----+-------------+
| 1 | CAT,DOG |
+----+-------------+
| 2 | CAT,DOG,TIG |
+----+-------------+
| 3 | ZEB,MOU |
+----+-------------+
Now I want to list all id's where pets = CAT, similarly all id's where pets = DOG etc
My initial try was to RUN the following SQL for each and every PET (CAT, DOG, etc)
select id
from "favpets"
where pets like '%CAT%'
The limitation of this simple solution is that the actual table and no. of pets are not as simple as mentioned above.
No. of such pets are more than 200. Therefore, 200 sql's have to be executed in order to list all id's corresponding to the pets
Is there any good alternative solution ? I'm using doctrine, so does doctrine provide any good implementation ?
With this query you will obtain all id, all pets, ordered by pet:
SELECT id, unnest(string_to_array(pets, ',')) AS mypet
FROM favpets
ORDER BY mypet;
Using it as subquery it will became easy to group and count:
SELECT mypet, COUNT(*) FROM
(
SELECT id, unnest(string_to_array(pets, ',')) AS mypet
FROM favpets
ORDER BY mypet
) AS a
GROUP BY mypet;

How to join (without concatenating) two result sets of two fields together as one long ‘list’

What SQL Code do I require to perform the following? :
I have one table (lets arbitrarily call the table 'Names'):
ID | Name1 | Name2
---+--------+-------
1 | Fred | Jack
2 | Jack | Jim
3 | Jill | Fred
4 | Jim | Jack
etc
What I'd like is to produce is a single list of Name1 and Name2 (I don't even care about Grouping or Ordering) as such, but I would like to keep the original 'ID' association with the name:
ID | Names
---+------
1 | Fred
1 | Jack
2 | Jill
2 | Jim
3 | Jack
3 | Jim
4 | Fred
4 | Jack
Why do I want to do this? Because it looks easy and as a SQL coder I should probably be able to perform this task, but I can't figure out a solution that will create this output. Further more I've only manage to find people with the desire to concatenate the fields, which is a simple task, but I'm not interested in concatenation.
Additional Question: Would the SQL query be vastly different if Name1 field was in a different table to Name2? (if it is different, what would it look like?)
Additional Question: Would the SQL query be simpler if we didn't care about the ID field? If so, what would that look like.
You can use this form to include the id, and give you a specific ordering by ID.
SELECT n.id, n.name1 FROM names n
UNION
SELECT m.id, m.name2 from names m
ORDER BY id ASC;
If it were in a different table, the use of UNION doesn't have to change, since we're bringing the results from the table together, and ordering them by ID. This doesn't mean that the data is related, though.
SELECT n.id, n.name FROM name_one n
UNION
SELECT m.id, m.name from name_two m
ORDER BY id ASC;
If we didn't care about the ID field, it would be ever so lightly simpler - it's just selecting one column at that point.
SELECT ID, Name1 as Names FROM person
UNION
SELECT ID, Name2 as Names FROM person
?
. . What you mean by "without concatenating"?

SQL Two fields from tables of unassociated data into the same field?

I am trying to do this is SQL:
-------------------------------
Table A
-------------------------------
ID | Title
1 | Something Groovy
2 | Something Else
-------------------------------
Table B
-------------------------------
ID | Title
1 | Something Different
2 | Something More
Awesome Select Statement
-------------------------------
Both in one field
-------------------------------
Title
Something Groovy
Something Else
Something Different
Something More
Any Ideas?
Use UNION ALL to obtain the union of two selects. If you want to eliminate duplicates, use simply UNION.
SELECT Title FROM TableA
UNION ALL
SELECT Title FROM TableB
This is a simple union:
Select title from TableA
UNION
Select title from TableB
Note that any items that are identical will be eliminated.