I have a points table, where important columns are:
id userid orderid
1 10 150
2 10 150
3 15 151
4 12 152
5 11 152
I need to find all orderid which have multiple/various userid. The result would be:
id userid orderid
4 12 152
5 11 152
I can do it in PHP, but I hope someone have time to help me with mysql query. What I have tried so far is probably irrelevant.
Use COUNT(DISTINCT) and HAVING to find orderid with multiple various userid.
SqlFiddleDemo
SELECT t.*
FROM tab t
JOIN (SELECT orderid, COUNT(DISTINCT userid)
FROM tab
GROUP BY orderId
HAVING COUNT(DISTINCT userid) > 1) AS sub
ON t.orderid = sub.orderid
ORDER BY t.id
If you want to get just the rows that have same orderid but different userid, use this:
SELECT P1.* FROM points P1
INNER JOIN points P2
ON P1.orderid = P2.orderid and P1.id != P2.id and P1.userid != p2.userid;
Note that this first select returns what you expect in your question:
+----+--------+---------+
| id | userid | orderid |
+----+--------+---------+
| 4 | 12 | 152 |
| 5 | 11 | 152 |
+----+--------+---------+
Now, if you want to return ANY orderid that is the same, regardless of userid, use this:
SELECT P1.* FROM points P1
INNER JOIN points P2
ON P1.orderid = P2.orderid and P1.id != P2.id;
In this case, it won't exclude the result with same id, returning
+----+--------+---------+
| id | userid | orderid |
+----+--------+---------+
| 1 | 10 | 150 |
| 2 | 10 | 150 |
| 4 | 12 | 152 |
| 5 | 11 | 152 |
+----+--------+---------+
Related
I want to search TABLE1 and count which number_id has the most 5's in experience column.
TABLE1
+-------------+------------+
| number_id | experience |
+-------------+------------+
| 20 | 5 |
| 20 | 5 |
| 19 | 1 |
| 18 | 2 |
| 15 | 3 |
| 13 | 1 |
| 10 | 5 |
+-------------+------------+
So in this case it would be number_id=20
Then do an inner join on TABLE2 and map the number that matches the number_id in TABLE1.
TABLE2
+-------------+------------+
| id | number |
+-------------+------------+
| 20 | 000000000 |
| 29 | 012345678 |
| 19 | 123456789 |
| 18 | 223456789 |
| 15 | 345678910 |
| 13 | 123457898 |
| 10 | 545678910 |
+-------------+------------+
So the result would be:
000000000 (2 results of 5)
545678910 (1 result of 5)
So far I have:
SELECT number, experience, number_id, COUNT(*) AS SUM FROM TABLE1
INNER JOIN TABLE2 ON TABLE1.number_id = TABLE2.id
WHERE experience = '5' order by SUM LIMIT 10
But it's returning just
545678910
How can I get it to return both results and by order of number of instances of 5 in the experience column?
Thanks
This query will give you the results that you want. The subquery fetches all the number_id that have experience values of 5. The SUM(experience=5) works because MySQL uses a value of 1 for true and 0 for false. The results of the subquery are then joined to table2 to give the number field. Finally the results are ordered by the number of experience=5:
SELECT t2.number, t1.num_fives
FROM (SELECT number_id, SUM(experience = 5) AS num_fives
FROM table1
WHERE experience = 5
GROUP BY number_id) t1
JOIN table2 t2
ON t2.id = t1.number_id
ORDER BY num_fives DESC
Output:
number num_fives
000000000 2
545678910 1
SQLFiddle Demo
Add a group by clause:
SELECT number, experience, number_id, COUNT(*) AS SUM
FROM TABLE1
JOIN TABLE2 ON TABLE1.number_id = TABLE2.id
WHERE experience = '5'
GROUP BY 1, 2, 3 -- <<< Added this clause
ORDER BY SUM
LIMIT 10
Today I have posted a question and got a good answer: Stuck in building mysql query.
I though it helped me, but I've discovered that it returns wrong data. So I'm reposting the question here, with an answer I received, as well I will explain the problem why it is not working for me.
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
Offered solution:
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
The problem:
In the sub query the minimum ID is selected entire the group by (item_id) statement and doesn't reflects according to minimum bid_price.
In other words, the minimum id is selected not depending on the price field at all. So, in the result I will get minimum price and minimum id of the group, but this will not be the same row! The id can be related to the row with another bet_price value.
How this query can be adjusted? Thank you in advance!
SELECT min(m.id) AS id, m.item_id, m.user_id, m.bid_price
FROM my_table m
INNER JOIN (
SELECT item_id, min(bid_price) AS min_price
FROM my_table
GROUP BY item_id
) t ON t.item_id = m.item_id
AND t.min_price= m.bid_price
GROUP BY item_id
Output
id item_id user_id bid_price
1 1 11 1
7 2 17 1
8 3 18 2
Live Demo
http://sqlfiddle.com/#!9/a52dc6/13
SELECT DISTINCT
t1.item_id,
t1.bid_price
FROM tab1 t1
WHERE NOT exists(SELECT 1
FROM tab1 t2
WHERE t2.item_id = t1.item_id
AND t2.bid_price < t1.bid_price)
AND t1.item_id IN (1, 2, 3);
http://sqlfiddle.com/#!9/615e0a/5
I have the following tables:
purchase_tbl
id | productId | purchaseQuantity
---+-----------+-----------------
1 | 1 | 30
2 | 2 | 30
3 | 1 | 10
4 | 2 | 10
sale_tbl
id | productId | saleQuantity
---+-----------+-------------
1 | 1 | 10
2 | 2 | 10
3 | 1 | 10
4 | 2 | 10
5 | 1 | 10
6 | 2 | 10
I need to get the output as this one:
productId | totalPurchasedQuantity| totalSaleQuantity
----------+-----------------------+------------------
1 | 40 | 30
2 | 40 | 30
I'm using this query and how to get the desired result?
SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM purchase_tbl
JOIN sale_tbl
ON purchase_tbl.productId = sale_tbl.productId
GROUP BY purchase_tbl.productId
Current output
productId | totalPurchaseQuantity | totalSaleQuantity
----------+-----------------------+------------------
1 | 120 | 60
2 | 120 | 60
You better group then in separate query, as table have multiple records for each product, which getting cross product.
SELECT purchase.productId, totalPurchaseQuantity, totalSaleQuantity
FROM
(SELECT purchase_tbl.productId
, SUM(purchase_tbl.purchaseQuantity) AS totalPurchaseQuantity
FROM purchase_tbl
GROUP BY purchase_tbl.productId) purchase
INNER JOIN
(SELECT sale_tbl.productId
, SUM(sale_tbl.saleQuantity) AS totalSaleQuantity
FROM sale_tbl
GROUP BY sale_tbl.productId
) sale ON sale.productId= purchase.productId;
To obtain your expected result you have to do the aggregation on the individual table before joining them. Your query with be like:
SELECT A.productId, A.totalpurchaseQuantity, B.totalsaleQuantity
FROM
(SELECT productId, SUM(purchaseQuantity)
totalpurchaseQuantity FROM purchase_tbl
GROUP BY productId) A JOIN
(SELECT productId, SUM(saleQuantity)
totalsaleQuantity FROM sale_tbl
GROUP BY productId) B ON
A.productId=B.productId;
I have 3 tables that look like this:
acc_prop
id | pid | uid
1 | 10 | 1
2 | 11 | 1
3 | 12 | 1
cal
id | pid
1 | 10
2 | 11
3 | 12
price
cid | rate
1 | 100
2 | 99
3 | 130
I want to create a query that returns a pid, a count of uid's with the same uid, and the rate for that pid.
expected result
pid | uid_count | rate
10 | 3 | 100
11 | 3 | 99
12 | 3 | 130
my query looks like this
SELECT
cal.pid,
count(ap3.uid) as uid_count,
price.rate
FROM
price
JOIN
cal on cal.id = price.cid
JOIN
acc_prop ap using(pid)
JOIN
acc_prop ap2 on ap2.uid = ap.uid
JOIN
acc_prop ap3 on ap3.uid = ap2.uid
group by ap3.pid;
But it returns
the incorrect count
the incorrect pid list
the incorrect rate
actual result
pid | uid_count | rate
10 | 9 | 100
10 | 9 | 100
I think what you are after is this, viz to pre-calculate the number of users in acc_prop as a derived table, which you can then join through to the rest of the query:
SELECT
cal.pid,
UserCount.Cnt,
price.rate
FROM
price
JOIN cal on cal.id = price.cid
JOIN acc_prop ap using(pid)
JOIN
(
SELECT uid, COUNT(*) AS Cnt
FROM acc_prop
GROUP BY uid
) UserCount
ON ap.uid = UserCount.uid;
SqlFiddle here
I think cal is not needed here, do you tried this:
SELECT
acc_prop.pid, (SELECT COUNT(*) FROM acc_prop WHERE uid = uid) AS uid_count, price.rate
FROM
acc_prop
INNER JOIN price
ON acc_prop.id = price.cid
I have table like
table_id item_id vendor_id category_id
1 1 33 4
2 1 33 4
3 1 33 2
4 2 33 4
5 2 33 2
6 3 33 4
7 3 33 4
8 1 34 4
9 1 34 4
10 3 35 4
Here table_id is primary key and table having total 98000 entries including 61 duplicate entries which I found by executing query
SELECT * FROM my_table
WHERE vendor_id = 33
AND category_id = 4
GROUP BY item_id having count(item_id)>1
In above table table_id 1,2 and 6,7 duplicate. I need to delete 2 and 7 from my table( Total 61 Duplicate Entries). How can I delete duplicate entries from my table using query with where clause vendor_id = 33 AND category_id = 4 ? I don't want delete other duplicate entries such as table_id 8,9
I cannot index the table, since I need to kept some duplicate entries which required. I need to delete duplicate with certain criteria
Please always take backup before running any deletion query.
Try using LEFT JOIN like this:
DELETE my_table
FROM my_table
LEFT JOIN
(SELECT MIN(table_id) AS IDs FROM my_table
GROUP BY `item_id`, `vendor_id`, `category_id`
)A
ON my_table.table_id = A.IDs
WHERE A.ids IS NULL;
Result after deletion:
| TABLE_ID | ITEM_ID | VENDOR_ID | CATEGORY_ID |
------------------------------------------------
| 1 | 1 | 33 | 4 |
| 3 | 1 | 33 | 2 |
| 4 | 2 | 33 | 4 |
| 5 | 2 | 33 | 2 |
| 6 | 3 | 33 | 4 |
See this SQLFiddle
Edit: (after OP's edit)
If you want to add more conditions, you can add it in outer WHERE condition like this:
DELETE my_table
FROM my_table
LEFT JOIN
(SELECT MIN(table_id) AS IDs FROM my_table
GROUP BY `item_id`, `vendor_id`, `category_id`
)A
ON my_table.table_id = A.IDs
WHERE A.ids IS NULL
AND vendor_id = 33 --< Additional conditions here
AND category_id = 4 --< Additional conditions here
See this SQLFiddle
What about this:
DELETE FROM my_table
WHERE table_id NOT IN
(SELECT MIN(table_id)
FROM my_table
GROUP BY item_id, vendor_id, category_id)
try below code...
DELETE FROM myTable
WHERE table_ID NOT IN (SELECT MAX (table_ID)
FROM myTable
GROUP BY table_ID
HAVING COUNT (*) > 1)
Try
DELETE m
FROM my_table m JOIN
(
SELECT MAX(table_id) table_id
FROM my_table
WHERE vendor_id = 33
AND category_id = 4
GROUP BY item_id, vendor_id, category_id
HAVING COUNT(*) > 1
) q ON m.table_id = q.table_id
After delete you'll have
| TABLE_ID | ITEM_ID | VENDOR_ID | CATEGORY_ID |
------------------------------------------------
| 1 | 1 | 33 | 4 |
| 3 | 1 | 33 | 2 |
| 4 | 2 | 33 | 4 |
| 5 | 2 | 33 | 2 |
| 6 | 3 | 33 | 4 |
| 8 | 1 | 34 | 4 |
| 9 | 1 | 34 | 4 |
| 10 | 3 | 35 | 4 |
Here is SQLFiddle demo
From your Question, I guess you need to remove the duplicate rows which has same values for the item_id,vendor_id and category_id like the rows having tabled_id 1 and 2. So it can be done by making the mentioned three columns unique together. So try the following,
alter ignore table table_name add unique index(item_id, vendor_id, category_id);
Note: I didnt test this yet, Will give sqlfiddle in sometime