I have following MySQL table structure,
id product_id filter_tag_id
14 1 48
17 3 49
18 10 49
19 10 54
20 11 49
21 11 55
22 12 49
23 12 56
24 9 48
25 9 52
26 6 48
27 6 53
28 7 48
29 7 56
30 8 48
31 8 53
32 13 48
33 13 52
34 14 48
35 14 54
36 14 55
37 15 48
38 15 55
i need to fetch only those product_id's which have same filter_tag_id's,
For example only one product_id (9 and 13) having the same filter_tag_id (48 and 52), so I need to fetch only product_id 9 and 13, I'm trying following query, but no success yet.
select product_id from filter_data where filter_tag_id=52 AND filter_tag_id=48;
select product_id from filter_data where filter_tag_id in (52,48);
First query return no result and second one returning wrong results
Use self-join. It looks like more complicated than GROUP BY, but it is faster than group-by. Because with GROUP BY approach, those which only has 48 or 52 should be groupped that is not unneeded rows.
SELECT t1.product_id
FROM filter_data t1 INNER JOIN filter_data t2 ON t1.product_id = t2.product_id
WHERE t1.filter_tag_id = 48 AND t2.filter_tag_id = 52;
If what you want is to find only product_ids having filter_tag_id values equal to 48 and 52 and nothing else but these two values, then try:
SELECT product_id
FROM mytable
GROUP BY product_id
HAVING COUNT(CASE WHEN filter_tag_id = 48 THEN 1 END) > 0 AND
COUNT(CASE WHEN filter_tag_id = 52 THEN 1 END) > 0 AND
COUNT(CASE WHEN filter_tag_id NOT IN (48,52) THEN 1 END) = 0
Demo here
use GROUP BY
Select product_id,COUNT(DISTINCT filter_tag_id) filter_match
from filter_data where filter_tag_id in (52,48)
GROUP BY product_id
HAVING filter_match = 2
the value of filter_match is count you will pass in condition
Related
Please I need some guide on how to sum my NewConverts column as seen in the table below.
I have 2 tables with names tbl_cmleader and tbl_cmreport. I combine the 2
tables to run this query as seen below:
SELECT mdate AS MDate, WEEK(mdate) AS MWeek, WEEK(NOW()) AS CWeek, nconvt AS
NewConverts, tbl_cmreport.cml_id, tbl_cmleader.grp_id FROM tbl_cmreport INNER JOIN
tbl_cmleader ON tbl_cmreport.mem_id = tbl_cmleader.mem_id WHERE tbl_cmleader.grp_id = 12
and mdate = '2022-07-08' ORDER BY mdate DESC
After running this query, I get the result as seen below:
MDate
MWeek
CWeek
NewConverts
cml_id
grp_id
2022-07-08
27
28
5
142
12
2022-07-08
27
28
5
142
12
2022-07-08
27
28
5
142
12
2022-07-08
27
28
1
143
12
2022-07-08
27
28
1
143
12
2022-07-08
27
28
1
143
12
2022-07-08
27
28
1
143
12
2022-07-08
27
28
1
143
12
2022-07-08
27
28
1
131
12
2022-07-08
27
28
1
131
12
2022-07-08
27
28
1
131
12
2022-07-08
27
28
1
131
12
2022-07-08
27
28
1
131
12
2022-07-08
27
28
1
132
12
2022-07-08
27
28
1
132
12
2022-07-08
27
28
1
132
12
2022-07-08
27
28
1
132
12
2022-07-08
27
28
1
132
12
However, I can't use this result to achieve what I want because the values are much. So
I add a Group By to help reduce the contents and give me the right values as seen in the query below.
SELECT mdate AS MDate, WEEK(mdate) AS MWeek, WEEK(NOW()) AS CWeek, nconvt AS
NewConverts, tbl_cmreport.cml_id, tbl_cmleader.grp_id FROM tbl_cmreport INNER JOIN
tbl_cmleader ON tbl_cmreport.mem_id = tbl_cmleader.mem_id WHERE tbl_cmleader.grp_id = 12
and mdate = '2022-07-08' GROUP BY mdate, tbl_cmleader.cml_id ORDER BY mdate DESC
At the end I get this results below
MDate
MWeek
CWeek
NewConverts
cml_id
grp_id
2022-07-08
27
28
5
142
12
2022-07-08
27
28
1
143
12
2022-07-08
27
28
1
131
12
2022-07-08
27
28
1
132
12
2022-07-08
27
28
1
134
12
This is the final table I want. Now from this table, I want to SUM the
NewConverts column to get a value of 9 but instead I am getting 36.
I run this query below to SUM the NewConverts column. The value I expect after the summation is a 9 but instead I am getting 36.
SELECT mdate AS MDate, WEEK(mdate) AS MWeek, WEEK(NOW()) AS CWeek, SUM(nconvt) AS
NewConverts, tbl_cmreport.cml_id, tbl_cmleader.grp_id FROM tbl_cmreport INNER JOIN
tbl_cmleader ON tbl_cmreport.mem_id = tbl_cmleader.mem_id WHERE tbl_cmleader.grp_id = 12
and mdate = '2022-07-08'
I am getting 36 under column NewConverts buts that's not what I want
MDate
MWeek
CWeek
NewConverts
cml_id
grp_id
2022-07-08
27
28
36
142
12
What I want is a 9 under column NewConverts as seen below
MDate
MWeek
CWeek
NewConverts
cml_id
grp_id
2022-07-08
27
28
9
142
12
Please I need help on how to rewrite the query below to get the right result
SELECT mdate AS MDate, WEEK(mdate) AS MWeek, WEEK(NOW()) AS CWeek, SUM(nconvt) AS
NewConverts, tbl_cmreport.cml_id, tbl_cmleader.grp_id FROM tbl_cmreport INNER JOIN
tbl_cmleader ON tbl_cmreport.mem_id = tbl_cmleader.mem_id WHERE tbl_cmleader.grp_id = 12
and mdate = '2022-07-08'
Thank you in advance
Michael
Your queries will fail with sql_mode=only_full_group_by enabled. It is not a good practice to disable it.
To get your desired result in the query which gives the final table that you want , you could apply an outer query doing the SUM
SELECT MDate,
MWeek,
CWeek,
SUM(NewConverts) as tot_NewConverts,
max(cml_id) as max_cml_id,
grp_id
FROM (
SELECT mdate AS MDate,
WEEK(mdate) AS MWeek,
WEEK(NOW()) AS CWeek,
NewConverts,
tbl_cmleader.cml_id,
tbl_cmleader.grp_id
FROM tbl_cmleader
WHERE tbl_cmleader.grp_id = 12
AND mdate = '2022-07-08'
GROUP BY MDate,MWeek,CWeek,cml_id,NewConverts,cml_id,grp_id
) as t1
GROUP BY MDate,MWeek,CWeek,grp_id;
Note,I used only one table so I removed the inner join clause.
max(cml_id) is just to return the max cml_id, because of sql_mode=only_full_group_by disabled that returned value was arbitrary.
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=355eb49ad446b63ee507ffe93be54440
There are two campaigns running campaign A and Campaign B and list of user ids participated in those two campaign is given below. Calculate the number of users based on the below conditions by writing a single query.
Participated in campaign A
Participated in campaign B
Participated in campaign A only
Participated in campaign B only
Participated in both the campaigns
Participated in either campaign A or Campaign B
Campaign A Campaign B
user_id user_id
91 62
27 11
58 16
50 92
64 17
65 71
54 12
98 37
78 93
24 58
31 54
73 94
63 85
72 30
94 32
20 1
38 48
8 99
43 45
33 46
26 39
100 29
61 49
87 73
84 81
15 88
80 70
77 33
40 55
82
42
56
95
88
I am not able to figure out how to write in single SQL query.
Assuming you have two different tables, you can use union all and aggregation:
select in_a, in_b, count(*) as num_users
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u
group by in_a, in_b;
This gives you all the information you need. You can use group by in_a, in_b with rollup to get all combinations.
Or, you can summarize this into one row:
select sum(in_a) as in_a, sum(in_b) as in_b,
sum(in_a * (1 - in_b)) as in_a_only,
sum(in_b * (1 - in_a)) as in_b_only,
sum(in_a * in_b) as in_ab
from ((select user_id, 1 as in_a, 0 as in_b
from a
) union all
(select user_id, 0 as in_a, 1 as in_b
from b
)
) u;
Note: These both assume that users are unique in each campaign. If not, just use select distinct or union in the subquery.
I'm on MySQL 8.0.24, and I have a tree structure table named category, it has 3 columns: category_id, parent_id, image.
category_id
image
parent_id
69
68
70
68
71
68
60
57
61
60
62
57
63
62
64
57
65
64
66
57
67
66
68
57
53
52
54
52
55
52
56
52
57
41
58
57
59
58
18
14
19
18
20
18
21
1
22
21
23
22
24
22
25
21
26
25
27
26
28
26
I want to use the resultset of category_id obtained from another query, loop thru each element in the array and try to see if a given parent_id can be matched.
For example, the resultset of category_id is {98, 60, 26}, and I want to find out if any of the 3 elements has a parent_id of 1.
Analysis:
98's parent_id is NULL,
60's parent_id is 57, 41
26's parent_id is 25, 21, 1
Therefore a hit is found.
I tried to understand and use the following SQL from sql loop thru same table, with no luck...
with aa_category(category_id) as (select category_id from aa_category union all select nplus1.category_id from aa_category as nplus1, aa_category where aa_category.category_id = nplus1.parent_id) select category_id from aa_category;
How do I write this SQL?
you can use recursive cte:
with recursive cte as (
select *, category_id originalCategory from category
where category_id in (98, 60, 26)
union all
select c.*, cte.originalCategory from category c
join cte on cte.parent_id = c.category_id
)
select originalCategory,parent_id
from cte
where parent_id = 1
originalCategory
parent_id
26
1
db<>fiddle here
I have table like
id userid semid courseid coursename total
1 36 17 13 CA 23
2 36 17 5 CB 46
3 36 17 8 CC 20
4 36 19 16 CD 34
5 36 19 13 CA 31
6 36 19 3 CA# 29
7 36 19 7 CE 60
8 36 10 9 CK 32
9 36 10 15 CH 56
I need average of semid for a userid i.e., SUM(courseid) /count (moduleid), It was showing 9 as module count, but I have only 3 modules.
This is my query
SELECT userid, SUM(total)/count(semid) FROM custom WHERE userid=36
just use the AVG( ) function
SELECT userid, semid, AVG(total)
FROM custom
WHERE userid = 36
GROUP BY userid, semid
SQLFiddle Demo
SELECT userid, SUM(total)/count(distinct semid) FROM custom WHERE userid=36
Try this query
There is MYSQL aggregate function AVG() for finding Average . #John Totet Woo has posted the answer.
post_id organisation_id
1 5
2 57
3 57
4 57
5 58
6 59
7 60
8 61
8 62
9 59
11 57
12 57
4 62
is there anyway to select post_id, organisation_id1, organisation_id2 in a single row?
Since you didn't specify what your table looks like and what would be the outcome that you would like, this is just a guess.
SELECT
a.post_id,
a.organisation_id,
b.organisation_id
FROM your_table a
LEFT JOIN your_table b
ON a.post_id = b.post_id AND a.organisation_id < b.organisation_id
Is this what you're looking for?
select post_id, group_concat(organisation_id)
from YourTable
group by post_id;