MySQL Group two column with where clause on both two group - mysql

What I have:
I have two table , first is user_faktorha save invoices data and second is u_payment save payment data .
What I want:
I want to group all data from this two table and have a result as one table with sum both table.
My two table with sample query's is on sqlfiddle : http://sqlfiddle.com/#!2/b9f9e/4
What's problem:
I try to solve this problem , but give wrong result each time , for example (can be see on sqlfiddle) , user/tell named as habib on give wrong sum(price) result.
habib's faktorhaprice = -508261 and habib's paymentprice = 648000 but sum result in main query have wrong data -7115654 and 13000000
what's the solution ?

(Updated) One way:
SELECT tell,SUM(FAKTORHAPRICE) FAKTORHAPRICE, SUM(PaymentPrice) PaymentPrice
FROM (SELECT tell, price as FAKTORHAPRICE, null PaymentPrice
from user_faktorha
union all
SELECT Username as tell, null as FAKTORHAPRICE, Price as PaymentPrice
FROM `u_payment` WHERE Active='1') sq
GROUP BY tell ORDER BY FAKTORHAPRICE ASC;
SQLFiddle here.

The essence of your problem here is that you are trying to relate to unrelated tables. Sure they have common data in the user name, but there is not a clean relation between them like an invoice id that can be used to relate the items together such that the OUTER JOIN wouldn't duplicate records in your result set. My suggestion would be to do the aggregation on each table individually and then join the results like this:
SELECT f.tell, f.faktorhaprice, p.paymentprice
FROM
(SELECT tell, SUM(price) AS faktorhaprice FROM user_faktorha GROUP BY tell) AS f
INNER JOIN
(SELECT username, SUM(price) AS paymentprice FROM u_payment GROUP BY username) AS p
ON f.tell = p.username

Related

sum and diffrence from two sql table according to item - laravel

I'm trying to get the result of the sum of two different tables and find difference of this table: so here are my table
Orders Table
Ship Table
Table and Query
i need to get query result according to item if no quantity then ZERO Tried using ISNULL throws null all values and not result from IFNULL. code or SQL Query Which i have used.
select orders.item,
SUM(orders.quantity) as aQuantity,
SUM(ship.quantity) AS oQuantity,
SUM(orders.quantity) - SUM(ship.quantity) AS diffrence
FROM orders,
ship
GROUP BY orders.item
required Output
Give it a try:
select a.item,IFNULL(o_quant,0) as "o_quant",IFNULL(s_quant,0) as "s_quant",(IFNULL(sum(o_quant),0) - IFNULL(sum(s_quant),0)) as "difference" from (select o.item,sum(o.quantity) "o_quant"
from orders o group by o.item) a left join (select s.item,sum(s.quantity) "s_quant"
from ships s group by s.item) b on a.item = b.item group by a.item,o_quant,s_quant;

Use SELECT through three table

I tried to write a query, but unfortunately I didn't succeed.
I want to know how many packages delivered over a given period by a person.
So I want to know how many packages were delivered by John (user_id = 1) between 01-02-18 and 28-02-18. John drives another car (another plate_id) every day.
(orders_drivers.user_id, plates.plate_name, orders.delivery_date, orders.package_amount)
I have 3 table:
orders with plate_id delivery_date package_amount
plates with plate_id plate_name
orders_drivers with plate_id plate_date user_id
I tried some solutions but didn't get the expected result. Thanks!
Try using JOINS as shown below:
SELECT SUM(o.package_amount)
FROM orders o INNER JOIN orders_drivers od
ON o.plate_id=od.plate_id
WHERE od.user_id=<the_user_id>;
See MySQL Join Made Easy for insight.
You can also use a subquery:
SELECT SUM(o.package_amount)
FROM orders o
WHERE EXISTS (SELECT 1
FROM orders_drivers od
WHERE user_id=<user_id> AND o.plate_id=od.plate_id);
SELECT sum(orders.package_amount) AS amount
FROM orders
LEFT JOIN plates ON orders.plate_id = orders_drivers.plate_id
LEFT JOIN orders_driver ON orders.plate_id = orders_drivers.plate_id
WHERE orders.delivery_date > date1 AND orders.delivery_date < date2 AND orders_driver.user_id = userid
GROUP BY orders_drivers.user_id
But seriously, you need to ask questions that makes more sense.
sum is a function to add all values that has been grouped by GROUP BY.
LEFT JOIN connects all tables by id = id. Any other join can do this in this case, as all ids are unique (at least I hope).
WHERE, where you give the dates and user.
And GROUP BY userid, so if there are more records of the same id, they are returned as one (and summed by their pack amount.)
With the AS, your result is returned under the name 'amount',
If you want the total of packageamount by user in a period, you can use this query:
UPDATE: add a where clause on user_id, to retrieve John related data
SELECT od.user_id
, p.plate_name
, SUM(o.package_amount) AS TotalPackageAmount
FROM orders_drivers od
JOIN plates p
ON o.plate_id = od.plate_id
JOIN orders o
ON o.plate_id = od.plate_id
WHERE o.delivery_date BETWEEN convert(datetime,01/02/2018,103) AND convert(datetime,28/02/2018,103)
AND od.user_id = 1
GROUP BY od.user_id
, p.plate_name
It groups rows on user_id and plate_name, filter a period of delivery_date(s) and then calculate the sum of packageamount for the group

query to have all itms from one table but order by another table that doesn't have all items

I have one table products with id of product and name.
Second table is products_last_usage where I keep product_id, user_id and last_used_at.
Whenever a user clicks on a product, I have the field last_used_at updated.
Now, I need a query to list all products, and order them first by last_used_at, and then by name of product. It has to be PER USER. i.e. every user will have his own order of the table.
But I need all products, even if there are no records of them in the second table.
How to do that?
You can help me with a rails query or mysql query.
You can use a left join:
select p.*
from products p left join
products_last_usage plu
on plu.product_id = p.id and plu.user_id = $user_id
order by (last_used_at is not null) desc, last_used_at desc;
Ordering by last_used_at desc should also work. However, I think it is clearer to explicitly handle NULL values.
I think you can start from something like this. Pls next time post sample data, expected results etc.
SELECT A.PRODUCT_ID
, A.PRODUCT_NAME
, B.USER_ID
, B.LAST_USED_AT
FROM PRODUCTS A
LEFT JOIN PRODUCTS_LAST_USAGE B ON A.PRODUCT_ID = B.PRODUCT_ID
ORDER BY B.USER_ID, B.LAST_USED_AT DESC, A.PRODUCT_NAME;

SQL subquery going heywire

I am trying to fetch some combined result from two separate individual tables.
The transaction_fact table has around 3.6 million rows and translation_table has around 300000 rows.
Now i want a sum of amount for all transactions grouped by location and the product within that location. But as the fact table has only location id and product id and i would like the names in the result , I am using sub query.
My query is as follows:
SELECT
( SELECT translation
FROM translation_table
WHERE dim_name LIKE 'location_dim'
AND lang_id LIKE 'es'
AND dim_id LIKE CAST(o.loc_id AS CHAR(50))
AND field_name LIKE 'city') AS Location
, ( SELECT product_name
FROM prod_dim
WHERE prod_id = o.prod_id) AS Product
, SUM(amount)
FROM transaction_fact o
GROUP
BY loc_id
, prod_id
ORDER
BY loc_id
, prod_id;
But this query is not returning anything , just keeps on processing.
I waited for about one and half hour but still no result.
Please tell me what might be going wrong.
Joining the tables should eliminate the need for subqueries and give some performance boost. If not you may need to provide more details on the table structure before we can help. Something like this should get you started:
SELECT t.translation AS Location, p.product_name AS Product, SUM(o.amount) AS Total
FROM transaction_fact o
INNER JOIN translation_table t ON CAST(o.loc_id AS char(50)) = t.dim_id
INNER JOIN prod_dim p ON p.prod_id = o.prod_id
WHERE t.dim_name = 'location_dim'
AND t.lang_id = 'es'
AND t.field_name = 'city'
GROUP BY t.translation, p.product_name
ORDER BY o.loc_id, o.prod_id;
Notes: I've changed the LIKEs to =, as LIKE is for when you want to match on a pattern that includes wildcards.
The CAST that is used in the join to translation_table is not ideal. If you could do away with that you'd get better performance.

mysql group by multiple

I'm not sure if this is specifically a group by question, as I've tried grouping this by multiple columns. Basic problem is a table like this:
I would like to get the sum of the order total_price for different countries, but grouped by the order_id. So for France the sum of total_price should be 8000 as two of the rows are for the same order. My sql is clearly wrong as I am not getting this.
SELECT sum(total_price) as total_price_per_country
FROM cars
WHERE (country IN ('France'))
group by order_id, country;
Nope, GROUP BY won't quite get you that. If you GROUP BY country you get one row per country.
There's no way to do this without a second query, so it'd have to be something like this:
SELECT *, (SELECT SUM(total_price) FROM cars AS c2 WHERE c2.country = cars.country) AS total_price_per_country
FROM cars
(An INNER JOIN to a second copy of the table would work too.)
select sum(total_price) from cars where country = 'France' group by order_id
Try above query