SQL query returns wrong result set - mysql

I have this table:
columns:
Id product_id name status update_date
1 1 prod1 bought 2016-04-20 10:10:10
2 1 prod1 sold 2016-04-22 12:25:00
3 1 prod1 sold 2016-06-03 09:42:15
I wanna execute this query:
select id,name,status,max(update_date) from product group by name,status;
I get:
1 prod1 bought 2016-04-20 10:10:10
2 prod1 sold 2016-06-03 09:42:15
For the second row in the result set, I have to get:
3 prod1 sold 2016-06-03 09:42:15
and not: 2 prod1 sold 2016-06-03 09:42:15 !

Try this;)
select id,name,status,update_date from product
where (name, status, update_date) in (
select name,status,max(update_date) from product
group by name,status
)
Or
select t1.id, t1.name, t1.status, t1.update_date
from product t1
inner join (
select name,status,max(update_date) as update_date from product
group by name,status
) t2 on t1.name = t2.name and t1.status = t2.status and t1.update_date = t2.update_date

Simple Query, try this
select product_id,name,status,MAX(update_date) as date
from product group by product_id,name,status

select distinct A.id, A.name, A.status, A.update_date
from product A,
(select `name`,status,max(update_date) update_date
from product
group by `name`, status) B
where A.name=B.name and A.status=b.status and a.update_date=b.update_date
Explanations: the distinct is used in case you have 2 exact update_dates
SQLFiddle : http://www.sqlfiddle.com/#!9/b8218/2

I have tried the query and it is working.
CREATE TABLE ##product(
Id INT,
product_id INT,
name NVARCHAR(100),
status NVARCHAR(100),
update_date DATETIME
);
INSERT INTO ##product
VALUES
(1, 1, 'prod1', 'bought', '2016-04-20 10:10:10'),
( 2, 1, 'prod1', 'sold', '2016-04-22 12:25:00'),
(3, 1, 'prod1' , 'sold', '2016-06-03 09:42:15')
SELECT id, name, status, update_date FROM ##product WHERE update_date IN
(
SELECT MAX(update_date) FROM ##product GROUP BY name, status
)
DROP TABLE ##product

Related

MySQL Query for subtracting values from 2 tables

Hello I have this tables
Table A
ID Name Price QTY
1 name1 1000 10
2 name2 1200 5
Table B
ID Name Price QTY
1 name1 1000 2
I want to achieve
Table C
ID Name Price QTY
1 name1 1000 8
2 name2 1200 5
With my query SELECT DISTINCT ta.name, ta.price,(ta.quantity - tb.quantity) AS quantity, FROM TableA AS ta INNER JOIN TableB AS tb ON ta.id = tb.id
What I get is this
Table C
ID Name Price QTY
1 name1 1000 8
2 name2 1200 3
I sorry I really cant think of a way how to achieve what I want. Thanks for your help.
Your query actually gets you one line instead of two:
-- result set
# name, price, quantity
name1, 1000, 8
Based on your expected output,we can use:
SELECT ta.ID, ta.name, ta.price, ifnull((ta.QTY - tb.QTY),ta.QTY) AS quantity
FROM TableA AS ta
LEFT JOIN TableB AS tb
ON ta.name = tb.name and ta.price=tb.price;
-- result set:
# ID, name, price, quantity
1, name1, 1000, 8
2, name2, 1200, 5
This is the last updated answer I can give you for you updated request.Please consider firing a new question if it does not fulfill.
-- Supposing your latest tables have the following data.
insert TableA values
(1 , 'name1' , 1000 , 10)
,(2 , 'name2' , 1200 , 5);
insert TableB values
(1 , 'name1' , 1000 , 2),
(2 , 'name2', 1000 , 3)
;
-- You probably want this:
SELECT ta.ID, ta.name, ta.price, ifnull((ta.QTY - tb.QTY),ta.QTY) AS quantity
FROM TableA AS ta
LEFT JOIN TableB AS tb
ON ta.name = tb.name and ta.price=tb.price
union
SELECT Id , name , price , QTY
from TableB t
where not exists (select * from TableA where t.name=name and t.price=price)
;
-- result set:
# ID, name, price, quantity
1, name1, 1000, 8
2, name2, 1200, 5
2, name2, 1000, 3

Condition on join not working properly

I have two tables
customers (id, name....,created_at)
coupons (id, customer_id, ....,created_id)
I am trying to get count of all those coupons where created_at is 2015-12-29 and where customer's created_at is not 2015-12-29
select
count(*) as aggregate
from
`coupons`
where
(select count(*) from `customers`
where
`coupons`.`customer_id` = `customers`.`id`
and
DATE(`customers`.`created_at`) <> '2015-12-29') >= 1
and
DATE(`updated_at`) = '2015-12-29'
This query works fine, but when I add one more constraint to query client_id = 1, it doesnot work.
select
count(*) as aggregate
from
`coupons`
where
(select count(*) from `customers`
where
`coupons`.`customer_id` = `customers`.`id`
and
DATE(`customers`.`created_at`) <> '2015-12-29') >= 1
and
DATE(`updated_at`) = '2015-12-29'
and
`client_id` = 1
It should return non zero value, but it returns 0
Dummy data
customers
id, name, created_at
1 ehsan 2015-12-29 12:10:10
2 ehs 2015-12-28 12:10:10
coupons
id, customer_id, updated_at client_id
1 1 2015-12-29 12:10:10 1
2 2 2015-12-29 12:10:10 1
3 2 2015-12-29 12:10:10 1

Merging 2 Table and GROUP BY date

I need to merge multiple table group by the count base on date's day.
Below are my table structure :
#table1
id date
1 2015-07-01 00:00:00
2 2015-07-02 00:00:00
3 2015-07-03 00:00:00
#table2
id date
1 2015-07-02 00:00:00
2 2015-07-02 00:00:00
3 2015-07-02 00:00:00
4 2015-07-10 00:00:00
What I wanted to achieve :
#query result
date t1_count t2_count
2015-07-01 1 NULL
2015-07-02 1 3
2015-07-03 1 NULL
2015-07-10 NULL 1
Below are my query that refer to this link:
SELECT left(A.date,10) AS `day`
, COUNT(A.ID) AS `a_count`
, COUNT(B.ID) AS `b_count`
FROM table1 A
LEFT JOIN table2 B
ON LEFT(A.date,10) = LEFT(B.date,10)
GROUP BY LEFT(A.date,10)
UNION
SELECT left(B.date,10) AS `day`
, COUNT(A.ID) AS `a_count`
, COUNT(B.ID) AS `b_count`
FROM table1 A
RIGHT JOIN table2 B
ON LEFT(A.date,10) = LEFT(B.date,10)
GROUP BY LEFT(A.date,10);
but the result was
#query result
date t1_count t2_count
2015-07-01 1 0
2015-07-02 3 3
2015-07-03 1 0
2015-07-10 0 1
I'd try to modified and search other solution like UNION ALL, LEFT JOIN, etc, but I'd no luck to solve this problem.
You can do this using union all and group by:
select date, sum(istable1) as numtable1, sum(istable2) as numtable2
from ((select date(date) as date, 1 as istable1, NULL as istable2
from table1
) union all
(select date(date) as date, NULL as istable1, 1 as istable2
from table2
)
) t
group by date
order by 1;
Under some circumstances, it can be faster to aggregate the data in the subqueries as well:
select date, sum(numtable1) as numtable1, sum(numtable2) as numtable2
from ((select date(date) as date, count(*) as numtable1, NULL as numtable2
from table1
group by date(date)
) union all
(select date(date) as date, NULL as numtable1, count(*) as numtable2
from table2
group by date(date)
)
) t
group by date
order by 1;
If you want 0 instead of NULL in the desired results, use 0 instead of NULL in the subqueries.

Mysql Join to show all records with or without matching records

I have two tables. One for employees and another for ratings. Some employees have been rated others not. I'm trying to list all the employees with or without a rating value and sort them from the highest rating.
emp table
empid empName
--------------
1 John
2 Alex
3 Peter
4 Mary
Ratings table
ratingid | customerid | ratingvalue | empid
---------------------------------------------
1 1 4 1
2 6 2 1
3 4 3 3
4 5 5 4
Expected output:
empid | empName | avgrating | ratingcount
---------------------------------------------
1 John 3 2
2 Alex 0 0
3 Peter 3 1
4 Mary 5 1
I tried
SELECT *, round(AVG(ratingvalue ), 2) as avgrating, count(empid) as ratingcount
FROM emp LEFT JOIN ratings ON emp.empid = ratings.empid ORDER BY `avgrating`
DESC
That query doesn't produce the result I expect. It only gives me one row.
Thanks in advance
need group by and coalesce null values to 0.
SELECT EmpID, empName,
coalesce(round(AVG(ratingvalue ), 2),0) as avgrating,
coalesce(count(empid),0) as ratingcount
FROM emp
LEFT JOIN ratings
ON emp.empid = ratings.empid
GROUP BY EmpID, EmpName
ORDER BY `avgrating`DESC
I think this is what you want.
select
e.id, e.name,
avg(coalesce(t1.rating,0)) average_rating,
count(coalesce(t1.rating,0)) count_rating
from
(select '1' id, 'John' name union all
select '2' id, 'Alex' name union all
select '3' id, 'Peter' name union all
select '4' id, 'Mary' name) e
left join (select '1' id, '1' customer_id, '4' rating, '1' emp_id union all
select '2' id, '6' customer_id, '2' rating, '1' emp_id union all
select '3' id, '4' customer_id, '3' rating, '3' emp_id union all
select '4' id, '5' customer_id, '5' rating, '4' emp_id) t1 on
t1.emp_id = e.id
group by
e.id,
e.name
I have just subbed out your tables for data. You can run this in mysql directly and it should give you want you want.

Add Results of Three Subqueries

I have this table:
id item_name_1 quantity 1 item_name_2 quantity_2 item_name_3 quantity_3
-----------------------------------------------------------------------------------
1 Apple 2 Pear 3 Orange 5
2 Pear 1 Apple 4
3 Orange 6
4 Apple 1 Pear 2 Orange 3
I want this result:
item total
--------------
Apple 7
Pear 6
Orange 14
I tried this:
SELECT
(SELECT item_name_1, SUM(quantity_1) AS count FROM table1
GROUP BY item_name_1) AS item,
(SELECT item_name_2, SUM(quantity_2) AS count FROM table1
GROUP BY item_name_2) AS item,
(SELECT item_name_3, SUM(quantity_3) AS count FROM table1
GROUP BY item_name_3) AS item,
SUM(count) AS total
FROM table1
GROUP BY item;
Error Code: 1241. Operand should contain 1 column(s)
Any suggestions?
You're selecting two columns in your sub-queries when there can only be one column.
Something like this will get you what you are looking for:
SELECT item_name, SUM(quantity) AS quantity
FROM
(SELECT item_name_1 AS item_name, SUM(quantity_1) AS quantity
FROM table1
GROUP BY item_name_1
UNION ALL
SELECT item_name_2 AS item_name, SUM(quantity_2) AS quantity
FROM table1
GROUP BY item_name_2
UNION ALL
SELECT item_name_3 AS item_name, SUM(quantity_3) AS quantity
FROM table1
GROUP BY item_name_3) AS ABB1
GROUP BY item_name;
I would try it like this.
select t.item_name_1, s1+s2+s3
from
(
select * From
(
select sum(quantity_1) as s1, item_name_1
from
table1
group by item_name_1
) t1
full outer join
(
select sum(quantity_2) as s2, item_name_2
from
table1
group by item_name_2
) t2 on t1.item_name_1 = t2.item_name_2
full outer join
(
select sum(quantity_3) as s3, item_name_3
from
table1
group by item_name_3
) t3 on t2.item_name_2 = t3.item_name_3
) t