SQL Distinct Group By Query - mysql

Sample table data's
id id_order name phone price
1 4E0 A 789 $100
2 4E0 A 789 $100
3 4LK A 789 $200
4 2LP B 420 $50
5 DK2 B 420 $80
i want result be like the rows of distinct (id_order) where phone = "789"
id id_order name phone price
1 4E0 A 789 $100
3 4LK A 789 $200
or
id id_order name phone price
2 4E0 A 789 $100
3 4LK A 789 $200
I tried this but didn't get desired output:
SELECT DISTINCT (id_order), * from table_name WHERE phone= "789";

select
min(id) id,
id_order,
name,
phone,
price
from yourtable
group by id_order, name, phone, price

To always return one row per id_order - even if the name, phone or price is different - have a sub-query that returns each id_order's lowest id. JOIN with that result:
select t1.*
from table_name t1
join (select min(id) minid, id_order
from table_name
group by id_order) t2
on t1.id = t2.minid and t1.id_order = t2.id_order
where t1.phone = 789
Executes as:
SQL>select * from table_name;
id id_order name phone price
=========== ======== ==== =========== ===========
1 4E0 A 789 100
2 4E0 A 789 100
3 4LK A 789 200
4 2LP B 420 50
5 DK2 B 420 80
5 rows found
SQL>select t1.*
SQL&from table_name t1
SQL&join (select min(id) minid, id_order
SQL& from table_name
SQL& group by id_order) t2
SQL& on t1.id = t2.minid and t1.id_order = t2.id_order
SQL&where t1.phone = 789;
id id_order name phone price
=========== ======== ==== =========== ===========
1 4E0 A 789 100
3 4LK A 789 200
2 rows found

Related

MYSQL Stuck Generating temp table (massive query)

I have 4 tables (1 to many):
Dont say anything about that "email" relation. It is how my developer boss built it years ago.
EMPLOYEES (+-50 results)
------------------------------------------------
id name
1 EmpName 1
2 EmpName 2
CUSTOMERS (+50k results)
------------------------------------------------
id name email employee_assigned
1 John john#doe.com 12
2 Donald donald#duck.com 6
INTERESTS_CATEGORIES (+650k results)
------------------------------------------------
id customer_email category_id
1 john#doe.com 97
2 john#doe.com 13
3 donald#duck.com 56
4 donald#duck.com 126
5 donald#duck.com 45
INTERESTS_PRODUCTS (+650k results)
------------------------------------------------
id customer_email product_id
1 john#doe.com 78
2 john#doe.com 23
3 donald#duck.com 19
4 donald#duck.com 56
5 donald#duck.com 45
So I need to filter the customers by their assigned employee and their interests.
And here is the query:
SELECT
*
FROM
(
SELECT
customers.id AS 'id',
customers.name AS 'first_name',
customers.email,
employees.id AS 'employee_id'
FROM
customers,
employees
WHERE
employees.id = 2
AND
customers.employee_assigned = employees.id
) AS myCustomers
LEFT JOIN interests_categories
ON interests_categories.customer_email = myCustomers.email
LEFT JOIN interests_products
ON interests_categories.customer_email = myCustomers.email
WHERE
(
interests_categories.category_id = 20
OR
interests_categories.category_id = 21
)
GROUP BY myCustomers.email
So, the problem:
If the employee has a low number of assigned customers (like 3) query
is successfull.
If the employee has a medium-high number of assigned customers (over 100) query stucks.
I execute SHOW PROCESSLIST and it is stucked "Generating temp table".
Anyone has idea? :(
Thank you.
Check the indexes on your tables and try this:
SELECT
c.id AS 'id',
c.name AS 'first_name',
c.email,
e.id AS 'employee_id'
ic.*,
ip.*
FROM customers c
JOIN employees e
ON c.employee_assigned = e.id
LEFT JOIN interests_categories ic
ON ic.customer_email = c.email
LEFT JOIN interests_products ip
ON ic.customer_email = c.email
WHERE
(
ic.category_id IN (20,21)
AND e.id = 2
)
GROUP BY myCustomers.email
Incidentally, a less dumb design might look like as follows. If it was me, I'd start with this, and provide properly representative CREATE and INSERT statements accordingly. Also, I'm curious about where category_id comes from - because that's potentially an area for further optimization.
EMPLOYEES
------------------------------------------------
employee_id name
6 EmpName 1
12 EmpName 2
CUSTOMERS
------------------------------------------------
customer_id name email employee_assigned
1 John john#doe.com 12
2 Donald donald#duck.com 6
INTERESTS_CATEGORIES
------------------------------------------------
customer_id category_id
1 97
1 13
2 56
2 126
2 45
INTERESTS_PRODUCTS
------------------------------------------------
customer_id product_id
1 78
1 23
2 19
2 56
2 45

Update using data from another table

I want the minimum price from Table 2 to be filled in price column of Table 1 for a particular id.
Table 1
pid price
111 0
222 0
333 0
Table 2
pid price
111 100
111 200
222 120
222 90
333 200
333 150
Expected output: Table 1
pid price
111 100
222 90
333 150
You would do something like:
UPDATE Table1 t
SET t.price = (SELECT MIN(t2.price) FROM Table2 t2 WHERE t2.pid = t.pid);
this is query to get lowest price from table2
(SELECT price FROM table2 WHERE price = ( SELECT MIN(price) FROM table2 ) ) now you can update the table 1 ( update table1 set price="result you got from above query" where id=given id)

COUNT DUPLICATE RECORDS IN MYSQL

I need a query to count the duplicate records,
For Example
table name -customer
===================
customer_id-col name
222
111
222
222
111
122
output would be
customer_id count
222 3
111 2
222 3
222 3
111 2
122 1
i tried this query
SELECT customer_id,count( customer_id ) c
FROM customer
GROUP BY customer_id
HAVING c >1
output is
customer_id count
222 3
111 2
122 1
Is this possible Thanks in advance
Thanks
Raja
Try this
SELECT T.customer_id,S.duplicate_count FROM
(
SELECT customer_id,count(customer_id) AS duplicate_count
FROM yourtable group by customer_id
HAVING (duplicate_count > 0)
) AS S Join yourtable On S.customer_id = T.customer_id
FIDDLE DEMO
OP:
customer_id count
222 3
111 2
222 3
222 3
111 2
122 1
select customer_id,count(1) as count
from customer
group by customer_id

Add total of 3 rows for specific id

I have three tables:
Students
-------------------------------------------------------------
studentId first last gender weight
-------------------------------------------------------------
1 John Doe m 185
2 John Doe2 m 130
3 John Doe3 m 250
Lifts
-------------------
liftId name
-------------------
1 Bench Press
2 Power Clean
3 Parallel Squat
4 Deadlift
5 Shoulder Press
StudentLifts
------------------------------------------------
studentLiftId studentId liftId weight
------------------------------------------------
1 1 1 185
2 2 3 130
3 3 1 190
4 1 2 120
5 2 1 155
6 3 2 145
7 1 1 135
8 1 1 205
9 2 3 200
10 1 3 150
11 2 2 110
12 3 3 250
I would like to have four top lists:
Bench Press
Parallel Squat
Power Clean
Total of the above 3
I can successfully grab a top list for each specific lift using the following query:
SELECT s.studentId, s.first, s.last, s.gender, s.weight, l.name, sl.weight
FROM Students s
LEFT JOIN (
SELECT *
FROM StudentLifts
ORDER BY weight DESC
) sl ON sl.studentId = s.studentId
LEFT JOIN Lifts l ON l.liftId = sl.liftId
WHERE l.name = 'Bench Press'
AND s.gender = 'm'
AND s.weight > 170
GROUP BY s.studentId
ORDER BY sl.weight DESC
However, I am stuck on how to add the highest total of each lift for each student. How can I first find the highest total for each student in each lift, and then add them up to get a total of all three lifts?
Edit
The result set that I am looking for would be something like:
-------------------------------------------------
studentId first last weight
-------------------------------------------------
3 John Doe3 585
1 John Doe 475
2 John Doe2 465
I also forgot to mention that I would actually like two lists, one for students above 170 and one for students below 170.
SELECT -- join student a total weight to the student table
A.studentId,
A.first,
A.last,
C.totalWeight
FROM
Student A,
(
SELECT -- for each studet add the max weights
sum(B.maxWeight) as totalWeight,
B.studentID
FROM (
SELECT -- for each (student,lift) select the max weight
max(weight) as maxWeight,
studentId,
liftID
FROM
StudentLifts
GROUP BY
studentId,
liftID
) B
GROUP BY
studentId
) C
WHERE
A.studentID = C.studentId
-- AND A.weight >= 170
-- AND A.weight < 170
-- pick one here to generate on of the two lists.

Getting Max date from multiple table after INNER JOIN

I have two following tables
table 1)
ID | HOTEL ID | NAME
1 100 xyz
2 101 pqr
3 102 abc
table 2)
ID | BOOKING ID | DEPARTURE DATE | AMOUNT
1 1 2013-04-12 100
2 1 2013-04-14 120
3 1 2013-04-9 90
4 2 2013-04-14 100
5 2 2013-04-18 150
6 3 2013-04-12 100
I want to get reault in mysql such that it take the row from table two with MAX DEPARTURE DATE.
ID | BOOKING ID | DEPARTURE DATE | AMOUNT
2 1 2013-04-14 120
5 2 2013-04-18 150
6 3 2013-04-12 100
SELECT b.ID,
b.BookingID,
a.Name,
b.departureDate,
b.Amount
FROM Table1 a
INNER JOIN Table2 b
ON a.ID = b.BookingID
INNER JOIN
(
SELECT BookingID, MAX(DepartureDate) Max_Date
FROM Table2
GROUP BY BookingID
) c ON b.BookingID = c.BookingID AND
b.DepartureDate = c.Max_date
SQLFiddle Demo
Well,
SELECT * FROM `table2` ORDER BY `DEPARTURE_DATE` DESC LIMIT 0,1
should help