How to join two table to display sales for each id - mysql

I was trying to display the total sale of each id by combining the two table by using the id. I have two table 1. user table, 2. sales table
//user table
--------------
| id | name |
---------------
| 1 | yuki |
| 2 | soman |
---------------
// sales table
--------------
| id | total|
---------------
| 1 | 300 |
| 2 | 23 |
| 1 | 500 |
---------------
With my query it only display 1 sale witch is sales for yuki.
SELECT i.name,SUM(ROUND(s.total),2)) AS sales
FROM user i
INNER JOIN sales s
ON i.id = s.id
--------------
| name | sales|
---------------
| yuki | 800 |
---------------
I want to display the output like this, what did I missed from my query?
--------------
| name | sales|
---------------
| yuki | 800 |
|soman | 23 |
---------------

Your query needs a group by clause:
SELECT u.name, SUM(ROUND(s.total),2)) AS sales
FROM user u
INNER JOIN sales s ON s.id = u.id
GROUP BY u.id, u.name
Such error is much easier to spot when sql mode ONLY_FULL_GROUP_BY is enabled.
As an alternative, you might want to consider a correlated subquery, which avoids outer aggregation (it actually behaves like a LEFT JOIN, which is - probably - closer to what you want):
SELECT u.*,
(SELECT SUM(ROUND(s.total),2)) FROM sales s WHERE s.id = u.id) AS sales
FROM user u
Side note: user is a language keyword, hence not a good choice for a column name. Consider using something else, such as users for example.

Related

Displaying Latest Record and Join Multiple table

how do I join multiple tables and displaying each users sold item, display the latest record who sold the items
I need output like this
Sold by:
"jon" item "#1" "book" with a price of "1000"
tried :
SELECT uid , users.name AS uname, transact.transaction_id AS transacted INNER JOIN users on transaction_table.c_id=c_table.c_id
User table
--------------------------
| uid | name | timezone |
--------------------------
| 1 | jon | +1 gmt |
| 2 | mix | +2 gmt |
| 3 | vic | +1 gmt |
--------------------------
transaction table
-------------------------------
| transaction_id | uid | c_id |
-------------------------------
| dafsf22sdfssgs | 2 | 1 |
| 23425asda3afaa | 1 | 1 |
-------------------------------
C-table
------------------------
| c_id | c_name | price |
------------------------
| 1 | book | 1000 |
| 2 | comic | 100 |
| 3 | notes | 10 |
-------------------------
If you want to group by item name and get the total
select u.name,count(*) as count, c.c_name, c.price*count(*) as totalPrice from user u
inner join transaction t on u.uid=t.uid
inner join ctable c on c.c_id=t.c_id
group by c.c_name
If you want to query all the transactions
select u.name, c.c_name, c.price from user u
inner join transaction t on u.uid=t.uid
inner join ctable c on c.c_id=t.c_id
If you just want to return the last transaction info
select u.name, c.c_name, c.price from user u
inner join transaction t on u.uid=t.uid
inner join ctable c on c.c_id=t.c_id
order by t.transaction_id desc limit 1
And one more thing. It is a much much more better practice if your field names are consistent.

How to count rows in nested tables with one SQL query?

I have three tables. Each User can have multiple Subscriptions and each Subscription can have multiple Payments.
Me goal is to count all Payments for a single User using one SQL query. Is it possible to do and how?
In the case below, The result for a User with id 1 should be 2 (because the User has two Payments)
Users
+----+------+
| Id | Name |
+----+------+
| 1 | John |
+----+------+
Subscriptions
+----+--------+-----------+
| Id | userId | data |
+----+--------+-----------+
| 1 | 1 | some data |
+----+--------+-----------+
| 2 | 1 | some data |
+----+--------+-----------+
Payments
+----+----------------+--------+
| Id | subscriptionId | amount |
+----+----------------+--------+
| 1 | 1 | 30 |
+----+----------------+--------+
| 2 | 2 | 50 |
+----+----------------+--------+
try like below by using join and aggregation
SELECT u.id, u.Name, COUNT(p.id) AS numberofpayment
FROM users u
Left JOIN Subscriptions s ON u.Id=s.userId
Left JOIN Payments p ON s.id=p.subscriptionId
GROUP BY u.id, u.Name
You can try to do something like this:
SELECT COUNT(p.Id) AS PaymentCount
FROM Users u
LEFT JOIN Subscriptions s ON u.Id=s.userId
LEFT JOIN Payments p ON s.id=p.subscriptionId
WHERE u.Id = #yourUserID
Pay attention on COUNT(p.Id) - it means count of existing payments.
PS: this answer for #Kickstart.

MySQL - Selecting Duplicates across 3 columns and joining with another table to filter

I have a Purchases table, where I'm trying to select all rows where first name, surname and email are duplicates (for all 3).
Purchases table:
| purchase_id | product_id | user_id | firstname | surname | email |
| ------------- | -----------| ------------- | ----------- | --------- | ----------- |
| 1 | 1 | 777 | Sally | Smith | s#gmail.com |
| 2 | 2 | 777 | Sally | Smith | s#gmail.com |
| 3 | 3 | 777 | Sally | Smith | s#gmail.com |
| 4 | 1 | 888 | Bob | Smith | b#gmail.com |
Further to this, each product ID corresponds to a product type in a 'Products' table, and I'm trying to filter by 'lawnmower' purchases (so only product ID 1 & 2)
Products table:
| product_type | product_id |
| ------------- | -----------|
| lawnmower | 1 |
| lawnmower | 2 |
| leafblower | 3 |
I'm hoping to write a query that will return all purchases of the 'lawnmower' type where first name, last name, and email are duplicates (so would return the first two rows of the Purchases table).
This is where my query is at so far, however it's not returning accurate data (e.g. I know I have around 350 duplicates and it's returning 10,000 rows):
SELECT t. *
FROM database_name.purchases t
JOIN (
SELECT firstname, surname, email, count( * ) AS NumDuplicates
FROM database_name.purchases
GROUP BY firstname, surname, email
HAVING NumDuplicates >1
)tsum ON t.firstname = tsum.firstname
AND t.surname = tsum.surname
AND t.email = tsum.email
INNER JOIN database_name.products p2 ON t.product_id = p2.product_id
WHERE p2.product_type = 'lawnmower'
Just wanting to know what I need to tweak in my query syntax.
You know that you should be returning Sally Smith. Create a table from the results of your query above. Then Select * from that table where first_name=sally and surname=Smith. See if you can figure out where you are going wrong based on that. This will help you debug these type of issues yourself in the future.
Your inner SELECT does not filter on the product type. It gets all customers who have purchased any two items. Then you join it to purchases and therefore also get the purchases of customers who have bought any two items and, possibly only one, lawnmower. Add a filter on the product type in the subquery too:
SELECT t.*
FROM database_name.purchases t
INNER JOIN (SELECT purchases.userid
FROM database_name.purchases
INNER JOIN database_name.products
ON products.product_id = purchases.product_id
WHERE products.product_type = 'lawnmower'
GROUP BY userid
HAVING count(*) > 1) s
ON t.user_id = s.user_id
INNER JOIN database_name.products p
ON t.product_id = p.product_id
WHERE p.product_type = 'lawnmower';
Your schema also is problematic -- denormalised. firstname, surname and email depend on user_id (Note that I only grouped and joined using the user_id, that's enough,). So they shouldn't be in purchases, only user_id. product_type better by an ID referencing to some product type table too.

SQL Join vs Sub-query

I'm running MySQL 5.1.71. In my database there are three tables - load, brass and mfg with load being my "main" table. My goal is to query load and have mfg.name included in the results. I've tried various iterations of JOIN clauses vs sub-queries both with and without WHERE clauses. It seems this should be pretty trivial so I'm not sure how I can't arrive at the solution.
load
-------------------------
| id | desc | brass_id |
-------------------------
| 1 | One | 2 |
| 2 | Two | 1 |
-------------------------
brass
---------------
| id | mfg_id |
---------------
| 1 | 6 |
| 2 | 8 |
---------------
brass_mfg
------------------------
| id | name |
------------------------
| 6 | This Company |
| 8 | That Company |
------------------------
My desired results would be...
results
---------------------------
| load | mfg |
---------------------------
| One | That Company |
| Two | This Company |
---------------------------
A load ID will always have only a single brass ID
A brass ID will always have only a single mfg ID
EDIT
The previously provided sample data (above) has been updated. Also, below are the query I'm running and the results I'm getting. The company is wrong in each record that is returned. I've included in the query and the results the IDs across the tables. The company names that appear are not the names in for the IDs in the mfg table.
SELECT
load.id AS "load.id",
load.brass_id AS "load.brass_id",
brass.id AS "brass.id",
brass.mfg_id AS "brass.mfg_id",
brass_mfg.id AS "brass_mfg.id",
brass_mfg.name AS "brass_mfg.name"
FROM `load`
LEFT JOIN brass ON load.brass_id = brass.id
LEFT JOIN brass_mfg ON brass.id = brass_mfg.id
-----------------------------------------------------------------------------------------
| load.id | load.brass_id | brass.id | brass.mfg_id | brass_mfg.id | brass_mfg.name |
-----------------------------------------------------------------------------------------
| 1 | 2 | 2 | 6 | 2 | Wrong Company |
| 2 | 1 | 1 | 8 | 1 | Incorrect Company |
-----------------------------------------------------------------------------------------
Look at your tables and see what data relates to one another then build up joins table by table to get your desired output.
SELECT p.desc AS Product, m.name AS mfg
FROM product p
INNER JOIN lot l ON p.lot_id = l.id
INNER JOIN mfg m ON l.mfg_id = m.id
If this is single - single relationship, why having middle table?
In your case the best scenario is simple join.
SELECT pt.desc as Product, mfg.name as Mfs
FROM Product pt
Join Lot lt on lt.id = pt.lot_id
Join Mfg mf on mf.id = lt.mfg_id
You have an error in your join query.
Try this one:
Select
l.id AS "load.id",
l.brass_id AS "load.brass_id",
b.id AS "brass.id",
b.mfg_id AS "brass.mfg_id",
m.id AS "brass_mfg.id",
m.`name` AS "brass_mfg.name"
FROM `load` as l
LEFT JOIN brass as b ON l.brass_id = b.id
LEFT JOIN brass_mfg as m ON b.mfg_id = m.id
You need LEFT JOIN only

MySQL Join Without Duplicates

I have a customers table, and an orders table. Each customer can have many orders.
I want to select every customer, along with their earliest order number from the orders table (it is important that I select the earliest order number, not just any order). I want to list customers whether they have an order or not, and I don't want to include customers twice if they have more than one order.
I'm using this:
SELECT *
FROM customers
LEFT JOIN orders
ON customers.id = orders.customer_id
GROUP BY customers.id
This gives me almost what I want, except it will pick whatever order ID it likes from the table. I need to be able to sort, and pick the smallest order ID.
Any ideas please?
Im pretty sure its something that's staring me in the face...
EDIT: Tables' Structures as requested
Customers:
| ID | Name | Address | Etc |
----------------------------------------
| 1 | Joe | 123 Fake Street | |
| 2 | Mike | 1600 Fake Road | |
| 3 | Bill | Red Square, Moscow | |
----------------------------------------
Orders:
| ID | Customer_ID | Date |
---------------------------
| 1 | 1 | ... |
| 2 | 2 | ... |
| 3 | 2 | ... |
| 4 | 1 | ... |
---------------------------
Create a virtual table (a/k/a subquery) with the lowest numerical order ID for each customer.
SELECT customer_id, min(order_id)
FROM orders
GROUP BY customer_id
Then join that table with the customer table, like so.
SELECT C.customer_id, firstorder.order_id
FROM CUSTOMERS as C
LEFT JOIN (
SELECT customer_id, min(order_id)
FROM orders
GROUP BY customer_id
) AS firstorder ON c.customer_id = firstorder.customer_id
Try this
Select customer.*,Order.OrderNo As EarilerORderNo
From Customers Left Join
(Select customer_id,orderid from orders order by customer_id,orderid desc) As Orders
ON Customers.Id=Orders.OrderID