Counting patterns from table mysql - mysql

I have the following data in a Mysql table
ID | code | code order
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
2 | 1 | 1
2 | 2 | 2
2 | 3 | 3
3 | 1 | 1
3 | 4 | 2
3 | 5 | 3
4 | 1 | 1
4 | 4 | 2
4 | 5 | 3
4 | 6 | 4
How would I write a query to return the following results
code pattern 1,2,3 = 2 (count)
code pattern 1,4,5 = 1 (count)
code pattern 1,4,5,6 = 1 (count)
basically I need to find out the most popular code sequence, each sequence is grouped by an unique ID. The order the codes of the is also important. i.e
1,4,5,6 is different to 1,5,4,6
cheers

In MySQL, this is probably most easily done using two aggregation:
select pattern, count(*)
from (select id, group_concat(code order by code) as pattern
from t
group by id
) p
group by pattern;

Related

How can I get the last row of every stage of every job? [duplicate]

This question already has an answer here:
Mysql group by two columns and pick the maximum value of third column
(1 answer)
Closed 2 years ago.
I've been taking too long trying to solve this, I need to filter this table:
+----+-------+-------+
| id | jobID |stageID|
+----+-------+-------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 2 |
| 4 | 1 | 1 |
| 5 | 2 | 2 |
| 6 | 2 | 1 |
| 7 | 2 | 1 |
| 8 | 2 | 2 |
+----+-------+-------+
You see every job has many rows with different stages, I need to get the last row of every stage of every job.
For example, look at job 1. It has 4 rows, each one with a given stage. I'd need to get the last entry of a stage for that job, which means, rows 3 and 4.
So for the full table I need to get rows No. 3, 4, 7 and 8, like this
+----+-------+-------+
| id | jobID |stageID|
+----+-------+-------+
| 3 | 1 | 2 |
| 4 | 1 | 1 |
| 7 | 2 | 1 |
| 8 | 2 | 2 |
+----+-------+-------+
I think I'll go nuts. I try with GROUP_BY but it groups the stages without taking in count the jobs.
Can you help me?
This is simply:
select max(id) as id, jobID, stageID
from yourtable
group by jobID, stageID
If you need additional information selected, use that as a subselect:
select yourtable.id, yourtable.jobID, yourtable.stageID, yourtable.other
from (
select max(id) as id
from yourtable
group by jobID, stageID
) max_job_stage_ids
join yourtable using (id)
or use IN (I find this less helpful in visualizing the query plan, but some people prefer it):
select id, jobID, stageID, other
from yourtable
where id in (select max(id) from yourtable group by jobID, stageID)

SQL: Get top users that follow same users

I have the table followers that looks like this:
id |follower_id|followee_id|
1 | 1 | 2 |
2 | 1 | 3 |
2 | 1 | 4 |
3 | 2 | 3 |
4 | 2 | 4 |
5 | 3 | 2 |
6 | 4 | 6 |
Where follower is a user_id and followee is the user they follow.
How can I find the users that have the most common followees with let's say user 1?
The results need to be ordered by number of common followees.
For example for the current table the results for user 1 would be:
follower_id|common_followees|
2 | 2 |
3 | 1 |
As you can see 4 does not appear in results since it has no common followees with user 1
I hope I explained the problem right.
Thank You.
This is a self-join and aggregation:
select f.follower_id, count(*) as num_common_followees
from followers f join
followers f1
on f.followees = f1.followees and f1.follower_id = 1
group by f.follower_id;
You can add where f.follower_id <> 1. I like to leave that row in as a validation check.

MySQL Select distinct row where one column is identical, and 2nd column is "3" or "4"

I have a table with data that looks something like this:
+------+--------+------------+
| id | Action | GeoDataID |
+------+--------+------------+
| 1 | 3 | 117085664 |
| 2 | 4 | 117085664 |
| 3 | 3 | 117096940 |
| 4 | 3 | 117096404 |
+------+--------+------------+
Now, I want to get all GeoDataID's that only has action = 3, and not action = 4. PS!! 1 and 2 have IDENTICAL GeoDataID and should not return row 1 in the result.
As you can see from id 1 and 2 they have identical GeoDataID.
From this example I want output only id 3 and 4. I've been trying to google, but can't find anything similar to what I want.
From the example above, the result should be:
+------+--------+------------+
| id | Action | GeoDataID |
+------+--------+------------+
| 3 | 3 | 117096940 |
| 4 | 3 | 117096404 |
+------+--------+------------+
1 and 2 not included due to GeoDataID 117085664 having Action 4.
You can exclude the items which have the same GeoDataID but Action 4 by introducing the 'negative criteria' with NOT EXISTS:
SELECT mt1.id, mt1.Action, mt1.GeoDataID
FROM MyTable mt1
WHERE mt1.Action = 3
AND NOT EXISTS
(
SELECT 1
FROM MyTable mt2
WHERE mt2.Action = 4
AND mt2.GeoDataID = mt1.GeoDataID
);
SqlFiddle here

How to select only that what matches all parameters in many-to-many

Need to get only the records that match all the specified conditions in many-to-many relationship.
Greatly simplified tables look like
Catalog Catalog_Types Types
1 1 1 1
2 1 2 2
3 2 1 3
2 3 4
2 4
3 1
3 4
It easy to select from Catalog by 1 type, but i need select by 1 ore more, for example how to get from Catalog only those rows that have Types 1 and 2, so if it have 1 but haven't 2 it is not suitable.
I saw a similar question and the decision here, but for the SQL. There used except, i tried to replace it by equals on mySQL, but I do not know mySQL so well.
thank you in advance,
and sorry for my english
This type of query is called "set within set"
If you want to get catalog ids with two types (1 and 2) but may have other types
SELECT catalog_id
FROM catalog_type
WHERE type_id IN (1, 2)
GROUP BY catalog_id
HAVING COUNT(DISTINCT type_id) = 2
if want to make sure you get catalog ids with exactly two types (e.g. 1 and 2)
SELECT catalog_id
FROM catalog_type
GROUP BY catalog_id
HAVING SUM(type_id = 1) > 0
AND SUM(type_id = 2) > 0
AND COUNT(DISTINCT type_id) = 2;
if you want to get catalog ids which have at least two of three types (e.g. 1, 2, 4)
SELECT catalog_id
FROM catalog_type
WHERE type_id IN (1, 2)
GROUP BY catalog_id
HAVING (MAX(type_id = 1)
+ MAX(type_id = 2)
+ MAX(type_id = 4)) >= 2
Assuming that you have following in catalog_type
| CATALOG_ID | TYPE_ID |
------------------------
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
| 2 | 4 |
| 3 | 1 |
| 3 | 2 |
| 3 | 4 |
Sample output for above-mentioned queries:
query 1 query 2 query 3
| CATALOG_ID | | CATALOG_ID | | CATALOG_ID |
-------------- -------------- --------------
| 1 | | 1 | | 1 |
| 3 | | 3 |
Here is SQLFiddle demo for all these queries. Take a look and see how results differ.

Tricky sql query for popularity

ProductId | BrandId | Views
1 | 1 | 3
2 | 1 | 2
3 | 2 | 3
4 | 2 | 4
Need write sql query to return this values:
BrandId | ViewsSummary
1 | 5
2 | 7
Please, how to do it?
It's hardly "tricky" - you're simply looking to group your results with an appropriate aggregate function:
SELECT BrandId, SUM(Views) AS ViewsSummary FROM my_table GROUP BY BrandId
See it on sqlfiddle.