Group by is not working with where in clause mysql? - mysql

Hi I have two tables one is user and another one is user_details
The user table is
id name
---------
1 John
2 Tom
3 Amy
4 Kat
The user_details table is
id user_id money created_on
------------------------------------
1 1 2000 2016-12-01
2 1 5000 2016-12-02
3 1 6000 2016-12-03
4 2 2050 2016-12-01
5 2 5020 2016-12-02
6 3 6000 2016-12-04
And I need result like
name user_id money created_on
------------------------------------
John 1 6000 2016-12-03
Tom 2 5020 2016-12-02
Amy 3 6000 2016-12-03
Kat 4 NULL NULL
My question is I need records where the recent created_on of user_details table, for this I wrote following query but I am getting all the results could any one tell me what wrong in my query
SELECT * FROM `user` as `u` LEFT JOIN ( SELECT user_id,money,created_on FROM `user_details` WHERE created_on IN (SELECT MAX(created_on) FROM user_details group by user_id )) `userdata` ON `u`.`id` = `userdata`.`user_id`;

In your inner subquery, you just group by the user_id, but don't filter by the user_id of the user you are currently selecting in your other query.
In other words: You don't even need to group by user_id, just select the MAX(created_on) of the given user by using an alias in the outer subquery like so:
SELECT * FROM `user` as `u` LEFT JOIN
( SELECT user_id,money,created_on FROM `user_details` x WHERE created_on IN
(SELECT MAX(created_on) FROM user_details
WHERE x.user_id = user_details.user_id))
`userdata` ON `u`.`id` = `userdata`.`user_id`;

Related

SQL subquery to get all rows of columns where other column value does not exist

I have the following Accounts_Users table:
account_id | user_id
--------------------
1 | 60
2 | 60
3 | 60
1 | 50
3 | 50
3 | 40
And I want to retrieve all the user_id's which do not have rows with certain account_id For example if the account_id = 2 I want the result should be:
user_id
-------
50
40
Since user_id = 60 have record with account = 2.
How can I do it using subqueries or in any other way?
You use a subquery:
select distinct user_id
from Accounts_Users
where user_id not in (
select user_id from Accounts_Users where account_id = 2
)
Subquery way:
select distinct user_id
from accounts_users
where user_id not in (
select user_id
from accounts_users
where account_id = 2)
Join way:
select distinct a.user_id
from accounts_users a
left join accounts_users b on b.user_id = a.user_id
and b.account_id = 2
where b.user_id is null

The SUM of column in Join table SQL PHP not working [duplicate]

This question already has answers here:
MYSQL select join multiple table and SUM
(2 answers)
Closed 1 year ago.
I am trying to calculate and get the SUM of column count from table table_two. I am trying to fetch and get a sum of the column by the Left Join function. but it is not working correctly and the SUM of a column I am getting times of row to exist in table_two.
I am not perfect well in the union table with left JOIN could you please help me with how to use the union function in my code.
I show the multiple threads on this StackOverflow but believe me it was tough to understand and very big. that's why I am making here a small table for help and easily understandable.
Please help me don't mark it as duplicate and closed sir. I am trying for the past 1weeks but no code working.
I am trying the code is -
SELECT *, SUM(table_two.count) AS totalQTY, SUM(table_one.qty) AS totalReqQty
FROM table_one
LEFT JOIN table_two
ON table_one product_key = product_code
LEFT JOIN product_table
ON table_two.product_code = product_table.product_ids
table_one
| ID | product_key | insert_date | qty
|------|------------------|--------------|------
| 1 | 123456789 | 2021-02-01 | 150
------------------------------------------------
table_two
| ID | product_code | add_date | count
|------|-------------------|--------------|-------
| 1 | 123456789 | 2021-02-02 | 10
| 2 | 123456789 | 2021-02-03 | 20
| 3 | 123456789 | 2021-02-04 | 5
--------------------------------------------------
product_table
| ID | product_ids | product_name
|------|-------------------|----------------------
| 1 | 123456789 | XYZ
--------------------------------------------------
Expecting Output:
| ID | product_key | product_name | qty | count |
|------|-------------------|---------------------------------
| 1 | 123456789 | XYZ | 150 | 35 |
-------------------------------------------------------------
The query you showed us does not work.
If you want to summarize / roll up / your data by using aggregate functions like SUM() your best bet is to start by running the query without them. For example
SELECT *
FROM table_one
LEFT JOIN table_two
ON table_one.product_key = table_two.product_code
LEFT JOIN product_table
ON table_two.product_code = product_table.product_ids
You get this result. Notice that it has three rows, and the qty 150 shows up in all three.
ID
product_key
insert_date
qty
ID
product_code
add_date
count
ID
product_ids
product_name
1
123456789
2021-02-01
150
1
123456789
2021-02-02
10
1
123456789
XYZ
1
123456789
2021-02-01
150
2
123456789
2021-02-03
20
1
123456789
XYZ
1
123456789
2021-02-01
150
3
123456789
2021-02-04
5
1
123456789
XYZ
Then, keep in mind that when you sum up multiple rows, the detail in those rows (for example, table_1.ID) isn't meaningful any more. Which ID do you want when three rows are added up?
So you can do something like this
SELECT table_one.product_key,
SUM(table_two.count) totalQty,
SUM(table_one.qty) totalReqQty
FROM table_one
LEFT JOIN table_two
ON table_one.product_key = table_two.product_code
LEFT JOIN product_table
ON table_two.product_code = product_table.product_ids
GROUP BY table_one.product_key
That gives this result, which is incorrect -- it triple-sums table_one.qty. Your JOIN of table_one and table_two caused a combinatorial explosion.
product_key
totalQty
totalReqQty
123456789
35
450 WRONG!
So, what you need in is to understand that your top level FROM table_one ... JOIN table_two ... JOIN product_table... pattern needs to join together a single row in table_one, table_two, and product_table for each product. In this setup you're fine for product_table. It has one row for each product.
But the other tables can have multiple rows per product. So you need to SUM them in subqueries, and join the subqueries, like this.
SELECT product_table.product_ids,
table_two_summary.totalQty,
table_one_summary.totalReqQty
FROM product_table
LEFT JOIN (
SELECT product_code, SUM(count) totalQty
FROM table_two
GROUP BY product_code
) table_two_summary
ON product_table.product_ids = table_two_summary.product_code
LEFT JOIN (
SELECT product_key, SUM(qty) totalReqQty
FROM table_one
GROUP BY product_key
) table_one_summary
ON product_table.product_ids = table_one_summary.product_key
Edit if you need to filter on the summed-up columns you can do it like this.
SELECT product_table.product_ids,
table_two_summary.totalQty,
table_one_summary.totalReqQty
FROM product_table
LEFT JOIN (
SELECT product_code, SUM(count) totalQty
FROM table_two
GROUP BY product_code
) table_two_summary
ON product_table.product_ids = table_two_summary.product_code
LEFT JOIN (
SELECT product_key, SUM(qty) totalReqQty
FROM table_one
GROUP BY product_key
) table_one_summary
ON product_table.product_ids = table_one_summary.product_key
WHERE table_one_summary.totalReqQty > table_two_summary.totalQty
See how the subqueries summarize the two different tables separately. If you join them and summarize them you'll count some rows multiple times.
You haven't tagged the database you are using, however one way to obtain the aggregations from each would be using apply.
I would also suggest you amend the inconsistencies in the naming convention of your ProductId, you are referring to it as product_code and product_key and product_ids. Deciding what to call it and being consistent will make it much easier for others to understand.
select p.product_ids as product_key, p.product_name, coalesce(q.Qty,0) totalQty, coalesce(c.[count],0) [Count]
from product_table p
outer apply (
select sum(qty) Qty
from table_one t1
where t1.product_key=p.product_ids
group by t1.product_key
)q
outer apply (
select Sum(count) [count]
from table_two t2
where t2.product_code=p.product_ids
group by t2.product_code
)c

Ask about Query in MySQL

I have table like this:
CreateDate | UserID
2012-01-1 | 1
2012-01-10 | 2
2012-01-20 | 3
2012-02-2 | 4
2012-02-11 | 1
2012-02-22 | 2
2012-03-5 | 3
2012-03-13 | 4
2012-03-17 | 5
I need the query to show UserID which created after 1 February 2013 and not exist in database befor 1 February 2013
From the above example the result must be:
CreateDate | UserID
2012-02-2 | 4
2012-03-13 | 4
2012-03-17 | 5
Can it resolved only in single query without Stored Procedure?
You can use a subquery which separately gets the UserID which exist before Feb. 2, 2013 and the result of the subquery is then joined back on the table itself using LEFT JOIN.
SELECT a.*
FROM tableName a
LEFT JOIN
(
SELECT UserID
FROM tableName
WHERE CreateDate < '2013-02-01'
) b ON a.userID = b.userID
WHERE a.CreateDate > '2013-02-01' AND
b.userID IS NULL
SQLFiddle Demo
for faster performance, add an INDEX on column userID.
SQL JOIN vs IN performance?
This is one way to do it:
select
CreateDate,
UserID
from Users
where CreateDate >= '2012-02-01'
and UserId not in (
select UserId
from Users
where CreateDate < '2012-02-01'
)
SqlFiddle link: http://www.sqlfiddle.com/#!2/7efae/2

Mysql SUM based another calculated filed condition

There are three tables Users, Lists, Details. Here it is my table structure and data sample
userid username | list_id list_val user_id | detail_id list_id multipler
1 user1 | 1 500 1 | 1 1 3
2 user2 | 2 300 1 | 2 1 2
3 user3 | 3 600 1 | 3 2 1
4 100 2 4 2 1
5 3 4
SELECT
users.username,
SUM(lists.lists_var),
FROM
users
INNER JOIN lists ON users.userid = lists.user_id
GROUP BY
users.username
HAVING
(SELECT (exp(sum(log(COALESCE(details.multipler, 1))))) FROM details WHERE
details.list_id = lists.list_id) > 3
This query gives me result
user1 - 1400
But I want something IF multipler_total > 3 THEN SUM(list_val) so result must be:
user1 - 1100
try this:
SELECT
users.username,
SUM(lists.lists_var),
FROM
users
INNER JOIN lists ON users.userid = lists.user_id
INNER JOIN (SELECT list_id, SUM(multiplier) mult_total FROM details GROUP BY list_id) d
ON d.list_id = lists.list_id and d.mult_total > 3
GROUP BY
users.username

Join data as different row from 3 different tables when structure are different and data are different

I am new to sql, and been given a task to join 3 tables. Could someone please shed some light on this sql.
I have 3 tables, like
Table 1
userID | username | password
1 user1 user1
2 user2 user2
table 2
userID | order number | order quantity
2 101 100
table 3
userID | name | address
1 John xxx
2 Will xxx
3 Peter xxx
And the result table needs to be displayed as:
UserID | username | name | address | order number | order quantity
1 user1 John xxxxx 0 0
2 user2 Will xxxxx 101 100
3 user3 Peter xxxxx 0 0
You should use LEFT JOIN with COALESCE on some columns,
SELECT a.`userid`,
a.`username`,
c.`name`,
c.`address`,
COALESCE(b.`order number`, 0) `order Number`,
COALESCE(b.`order quantity`, 0) `order quantity`
FROM table1 a
LEFT JOIN table2 b
on a.userid = b.userid
LEFT JOIN table3 c
on a.userid = c.userid
Basically, what LEFT JOIN does is to retrieve all rows from the left table whether it has a match on the second table or not. COALESCE handles what null values should be looked like.
This will help
select
a.userID,
c.name,
c.address,
b.order_number,
b.order_quantity
from
table1 a
join table3 c
on a.userID=c.userID
join table2 b
on a.userID=c.userID
However, you might need to pick up a SQL book as this is a very simple thing to do.