Find duplicated combination of rows in an array - php

I got a 2D array like this:
row | user_id | risk_id | measure_id | description
---------------------------------------------------
0 | 73 | 12 | 32 | 'foo'
1 | 73 | 12 | 32 | 'bar'
2 | 31 | 23 | 31 | 'foobar'
3 | 31 | 23 | 31 | 'foo'
I want to check if the combination between user_id, risk_id and measure_id is unique, and if not return another 2D array with the rows being the user_id and the columns the row, like this
user_id | row_0 | row_1 | ......
--------------------------------
73 | 0 | 1 | ......
31 | 2 | 3 | ......

This is for finding duplicates, but will return rows, not columns:
SELECT x.user_id, x.row
FROM YOUR_TABLE x
JOIN (SELECT t.user_id
FROM YOUR_TABLE t
GROUP BY t.user_id, risk_id, measure_id
HAVING COUNT(t.user_id) > 1) y ON y.user_id= x.user_id;
This one will return a table grouped by user_id, and duplicated rows stored comma separated in column rows:
user_id | rows
72 | 0, 1
31 | 2, 3
SELECT x.user_id, GROUP_CONCAT(x.row SEPARATOR ',') as rows
FROM YOUR_TABLE x
JOIN (SELECT t.user_id
FROM YOUR_TABLE t
GROUP BY t.user_id, risk_id, measure_id
HAVING COUNT(t.user_id) > 1) y ON y.user_id= x.user_id
GROUP BY x.user_id;

Related

Selecting max value while group by two columns with order on another column

I have table with 4 rows
id season_id market elements I would like to select for each same season_id, market that hold max result and if max results are the same then max based on elements only where elements are higher than 9.
id | season_id | market | result | elements
1 | 20 | fh | 75 | 20
2 | 20 | fh | 75 | 22
3 | 20 | SH | 81 | 18
4 | 20 | SH | 75 | 20
5 | 21 | fh | 90 | 14
6 | 21 | fh | 86 | 16
7 | 21 | SH | 90 | 18
8 | 21 | SH | 91 | 2
I would like to get
id | season_id | market | result | elements
2 | 20 | fh | 75 | 22
3 | 20 | SH | 81 | 18
5 | 21 | fh | 90 | 14
7 | 21 | SH | 90 | 18
I've tried
SELECT a.* FROM results a INNER JOIN (SELECT id, market, MAX(result) as perc FROM
results where elements>9 group by market ) group ON a.market = group.market and
a.result = group.perc group by market
But it doesn't select all the markets and I'm not sure how to add selection by number of elements to that
You seem to want one result per season_id/market pair. I'm not 100% sure what the limit on elements > 9 is supposed to be doing, but I think it is an overall filter.
To get the rows with the maximum result and elements for each season and market, use row_number():
select t.*
from (select t.*,
row_number() over (partition by season_id, market order by result desc, elements desc) as seqnum
from t
where elements > 9
) t
where seqnum = 1;
Here is a db<>fiddle.
In older versions of MySQL (or even more recent versions), you can use a correlated subquery:
select t.*
from t
where t.id = (select t2.id
from t t2
where t2.season_id = t.season_id and t2.market = t.market and
t2.elements > 9
order by t2.result desc, t2.elements desc
limit 1
);

Stuck in building MySQL query

Given an example of table:
id | item_id | user_id | bid_price
----------------------------------
The task is to select rows with minimum bid_price for each item_id in the provided set.
For example: item_id = [1, 2, 3] - so I need to select up to three (3) rows, having a minimum bid_price.
Example of data:
id | item_id | user_id | bid_price
----------------------------------
1 | 1 | 11 | 1
2 | 1 | 12 | 2
3 | 1 | 13 | 3
4 | 1 | 14 | 1
5 | 1 | 15 | 4
6 | 2 | 16 | 2
7 | 2 | 17 | 1
8 | 3 | 18 | 2
9 | 3 | 19 | 3
10 | 3 | 18 | 2
Expected result:
id | item_id | user_id | bid_price
----------------------------------
1 | 1 | 11 | 1
7 | 2 | 17 | 1
8 | 3 | 18 | 2
Actually, I'm using Symfony/Docine DQL, but it will be enough with a plain SQL example.
For the all the columns in the rows you could use a inner join on subselect for min bid price
select m.id, m.item_id, m.user_id, m.bid_price
from my_table m
inner join (
select item_id, min(id) min_id, min(bid_price) min_price
from my_table
where item_id IN (1,2,3)
group by item_id
) t on t.item_id = m.item_id
and t.min_price= m.bid_price
and t.min_id = m.id
or .. if you have some float data type you could use a acst for unsigned
select m.id, m.item_id, m.user_id, cast(m.bid_price as UNSIGNED)
from my_table m
inner join (
select item_id, min(id) min_id, min(bid_price) min_price
from my_table
where item_id IN (1,2,3)
group by item_id
) t on t.item_id = m.item_id
and t.min_price= m.bid_price
and t.min_id = m.id
You can use MIN() with GROUP BY in the query:
SELECT id, item_id, MIN(bid_price) AS min_bid, user_id
FROM your_tbl
GROUP BY item_id
HAVING item_id in(1, 2, 3);
Use this query:
SELECT id, item_id, user_id, min(bid_price) as bid_price
FROM YOUR_TABLE_NAME
GROUP BY item_id;

How to fetch data from table as per column value using PHP and MySQL

I need to filter value from table as per column value using PHP and MySQL. Here is my data:
db_images:
image_id member_id subcat_id from_day to_day
1 220 56 1 3
2 220 56 1 3
3 220 56 1 1
4 120 22 1 5
5 120 22 2 4
Here is my query:
$qry=mysqli_query($connect,"select * from db_iamges group by member_id,subcat_id order by image_id desc");
Using my query I am getting a record like below:
image_id member_id subcat_id from_day to_day
3 220 56 1 1
I need the to_day should always be higher value. If same member_id and subcat_id is present the the to_day will be always higher value and the from_day will be always smaller value. The expected output should like below.
image_id member_id subcat_id from_day to_day
1 220 56 1 3
4 120 22 1 5
It seems you have syntax problems, because if you copy-paste, you put "db_iamges". I made a table:
mysql> select * from prueba1;
+----------+-----------+-----------+----------+--------+
| image_id | member_id | subcat_id | from_day | to_day |
+----------+-----------+-----------+----------+--------+
| 1 | 220 | 56 | 1 | 3 |
| 2 | 220 | 56 | 1 | 3 |
| 3 | 220 | 56 | 1 | 1 |
| 4 | 120 | 22 | 1 | 5 |
| 5 | 120 | 22 | 2 | 4 |
| 6 | 120 | 22 | 2 | 9 |
| 7 | 120 | 22 | 2 | 2 |
+----------+-----------+-----------+----------+--------+
7 rows in set (0.00 sec)
And:
mysql> select image_id, member_id, subcat_id, min(from_day), max(to_day) from prueba1 group by member_id, subcat_id order by image_id asc;
+----------+-----------+-----------+----------+-------------+
| image_id | member_id | subcat_id | from_day | max(to_day) |
+----------+-----------+-----------+----------+-------------+
| 1 | 220 | 56 | 1 | 3 |
| 4 | 120 | 22 | 1 | 9 |
+----------+-----------+-----------+----------+-------------+
2 rows in set (0.00 sec)
It is working
EDIT: Updated, as I didn't understand your main problem.
Select
T.*
From db_images t
Inner join (
Select member_id, subcat_id, max(to_day) to_day
db_images group by member_id,subcat_id
) t2 on t.member_id = t2.member_id
And t.Subcat_id = t2.subcat_id
And t.to_day = t2.to_day;
use max(column name) to get higher value .
select image_id, member_id,subcat_id,from_day, max(to_day) as to_day from from db_iamges group by member_id,subcat_id order by image_id desc
try this
select t1.* from db_images t1 inner join(select max(member_id) as
mid,max(subcat_id) as cid,min(from_day) as fdy from db_images group
by member_id) t2 on t1.member_id = t2.mid and t2.cid = t1.subcat_id
and t2.fdy = t1.from_day group by member_id order by image_id asc;
check here

Get customers that has more than 2 orders but logged in less than 3 times though SQL

I'm trying to get all customers who has more than 2 orders, but only logged in less than 3 times.
I'm logging when users are logging in.
But for some reason my returns only one row with wrong data...
"user_log" table (user_id 19 has logged in only once)
| user_log_id | date | user_id | type | module_id | unit_id |
|-------------|------|---------|------|-----------|---------|
| 1 |"date"| 19 | 1 | NULL | NULL |
| 2 |"date"| 20 | 1 | NULL | NULL |
| 3 |"date"| 20 | 1 | NULL | NULL |
| 4 |"date"| 20 | 1 | NULL | NULL |
| 5 |"date"| 20 | 1 | NULL | NULL |
|-------------|------|---------|------|-----------|---------|
"orders" table where user_id 19 has 2 orders (Removed unnecessary columns)
| order_id | user_id | status |
|----------|---------|--------|
| 10 | 19 | 1 |
| 11 | 19 | 1 |
| 12 | 20 | 1 |
| 13 | 21 | 1 |
| 14 | 31 | 1 |
|----------|---------|--------|
What i want (User_id has 2 orders, but has logged in less than 3 times)
| user_id |
|---------|
| 19 |
|---------|
This is how my SQL looks like right now.
$sql = "SELECT
ul.*, orders.order_id, orders.user_id, orders.firstname, orders.lastname, COUNT(ul.user_id) AS occourcence
FROM
orders
LEFT JOIN
user_log AS ul
ON
orders.user_id = ul.user_id
WHERE
orders.status = 1
AND
ul.type = 1
GROUP BY
orders.user_id
HAVING
COUNT(orders.user_id) > 1
ORDER BY
orders.order_id DESC";
select user_id,count(user_log_id) from user_log
where user_id in
(
select user_id from Orderes
group by user_id
having count(order_id) =2
)
group by user_id
having count(user_log_id) < 3
Avoiding any sub queries (and assuming you meant logged in 3 times, and making 2 or more orders - to match your example data):-
SELECT a.user_id
FROM user_log a
INNER JOIN orders b
ON a.user_id = b.user_id
GROUP BY a.user_id
HAVING COUNT(DISTINCT user_log_id) < 3 AND COUNT(DISTINCT order_id) >= 2;
SQL fiddle here:-
http://www.sqlfiddle.com/#!2/1b719/3
Try this
select o.user_id from
(
select user_id from orders
where status=1
group by user_id having count(*)>=2
) as o left join
(
select user_id from user_logs
where type=1
group by user_id having count(*)<3
) as l
on o.user_id=l.user_id

Php and MySQL GROUP_CONCAT with separator comma and search where concat by comma

Is it that possible to select in Group_concat with separator comma
and search where concat by comma
Here My sample of mysql :
products_attributes_id |products_id| options_id| options_values_id
39 | 31 | 3 | 3
35 | 30 | 2 | 2
38 | 30 | 1 | 1
40 | 31 | 2 | 2
41 | 30 | 1 | 4
42 | 30 | 1 | 5
43 | 31 | 1 | 4
I want to GROUP_CONCAT options_values_id
SELECT * , GROUP_CONCAT(options_values_id SEPARATOR ',') FROM products_attributes GROUP by products_id
products_attributes_id | products_id | options_id | options_values_id | options_values_id
35 | 30 | 2 | 2 | 2,1,4,5
39 | 31 | 3 | 3 | 3,2,4
Now my problem is How I will find the product_id by searching ( option_values_id with comma) if my value is 1,2 or 2,4 then I will get only product_id=30.
But if I got value 1,3 I will get nothing. Because product_id 30 don't have option_values_id 3
and product_id 31 don't have option_values_id 1.
I try this code but I can't get the product_id
SELECT * , GROUP_CONCAT( options_values_id
SEPARATOR ',' )
FROM `products_attributes` WHERE CONCAT(',',options_values_id,',') LIKE '%,1,2,%'
GROUP BY products_id
Try this:
SELECT
products_id ,
GROUP_CONCAT(options_values_id SEPARATOR ',') as ops
FROM
products_attributes
GROUP by
products_id
HAVING
FIND_IN_SET('1',ops)
OR FIND_IN_SET('3',ops)

Categories