consult sql join tables - mysql

I try make this consult in sql, but i dont know how.
I have a tables of product shops.
And i want a table similar this:
tshirt | jeans | number sells
---------------------------------------
tshirt1 | jean1 | 5
tshirt1 | jean2 | 4
tshirt1 | jean3 | 0
.............................
tshirt1 | jeanN | 3
This information i have in other table where i have shopping.
This table have a code of users and a row for buy with one product.
codeUser product buy
-------------------------
1 tshirt1
1 jeans1
2 jeans2
...............
I want know many people buy a tshirt1 and also buy one product of category2.
I have a view with product filter by category, example tshirt; and other view equals but filter other category, example jeans.
I need this view??, or i need other view??
I dont know how I will do the query
Thank you

First, you need to generate all the rows using a cross join. Then bring in the customer information.
I think it looks like this:
select t.product as tshirt, j.product as jeans,
count(distinct bj.codeUser)
from (select distinct product from buys where product like 'tshirt%') t cross join
(select distinct product from buys where product like 'jeans%') j left join
buys bt
on bt.product = t.product left join
buys bj
on bj.product = j.product and
bj.codeuser = bt.codeuser
group by t.product as tshirt, j.product;

Related

Combine inner join result to one column

I have one shop table and one item table. Shop table has many item, and my problem is I want to search multiple items that available in one shop.
shop table
id | name
---------
1 | Shop 1
2 | Shop 2
Item table
id | name | shop_id
----------------------
1 | JRC | 1
2 | sukhoy | 1
3 | sukhoy | 2
When I want to find item jrc and sukhoy, so it must showing Shop 1, because both two items are ready on Shop 1.
My expected output is
Output table
id | shopName | itemName
------------------------
1 | Shop 1 | JRC
2 | Shop 1 | sukhoy
My query is
select * from shops
inner join products as produk2 on produk2.shopId = shops.id and (produk2.name like "%sukhoy%")
inner join products as produk on produk.shopId = shops.id and (produk.name like "%jrc%")
It works because it using different alias per inner join.
But what I want is, how to combine the output from that 2 join without define different alias. Or how I can combine join result into one same column ?
I think this does what you want:
select p.shop_id
from products p
group by p.shop_id
having sum(p.name like '%jrc%') > 0 and
sum(p.name like '%sukhoy%') > 0;
This returns shop ids that have both products. Of course, you can join the results to shops to get more information about the shops.
You can just use one join:
select * from shops
inner join products as produk
on produk.shopId = shops.id
and (produk.name like "%jrc%" OR produk.name like "%sukhoy%")

MySQL gruop by when there is no aggregation

I have a table called booking_details.
id | tour_id | tour_fee| booking_id
1 | 1 | 200 | 1
2 | 2 | 350 | 1
3 | 1 | 200 | 2
4 | 2 | 350 | 3
tour_id refers to the Tours table and the booking_id refers Bookings table.
I want to get a report like this
tour_id 1 refers to New york tour
tour_id 2 refers to Paris tour
I need a generate a report something like this
tour name | total_income | number_of_bookings
New york tour| 400 | 2
Paris tour | 700 | 2
Here basicaly tour name, total income from that tour and number of bookings for that tour.
What I have done upto now is this. But this gives me a syntax error. It seems I can't group by results.
SELECT booking_details.*,Tours.name as name, count(Tours.id) FROM booking_details
inner join Tours on
booking_details.tour_id = Tours.id group by Tours.name;
How do I achive this using MySQL?
you have used aggregation count() in your query and from your requirement, it shows you need aggregation. when you used aggregation you have to put selection column in group by also
SELECT Tours.name as name,sum(tour_fee) income, count(Tours.id)
FROM booking_details
inner join Tours on
booking_details.tour_id = Tours.id group by Tours.name
As you used in selection booking_details.* which means every column of booking table but you have not put those column in group by so it thrown error
You are trying to select non aggregated columns which are not part of your GROUP BY clause.
Change your query like following.
SELECT t.NAME AS NAME,
Sum(bd.tour_fee) total_income,
Count(t.id) number_of_bookings
FROM booking_details bd
INNER JOIN tours t
ON bd.tour_id = t.id
GROUP BY t.NAME;
Small suggestion, as a good practice you should use alias names for tables when joining.
You need to add all other columns in group by except aggregated fields
SELECT
booking_details.tour_id,
Tours.name AS name,
SUM(tourfee) AS total_income,
COUNT(Tours.id)
FROM
booking_details
INNER JOIN
Tours ON booking_details.tour_id = Tours.id
GROUP BY
booking_details.tour_id, Tours.name

How to group by relation property b if property a is null

I have a table containing items, each item belongs to an store, e.g:
id | name | store_id | price
1 | hat | 1 | 110
2 | bag | 1 | 120
3 | coat | 2 | 130
A Store can be canonical or a duplicate. A canonical Store has canonical_id equal to null, and a duplicate Store has canonical_id equal to the ID of the canonical Store, e.g:
id | name | canonical_id
1 | NYC | null
2 | Bronx | 1
I need to group items by their Store to get the total stock value of all items at the store, e.g:
SELECT store_id, SUM(price) as `stock_value` FROM items GROUP BY store_id
This would produce 2 results, Store 1 has a stock_value of 230 and Store 2 has a stock_value of 130.
Because Store 2 is a duplicate of Store 1 the items from Store 2 should be included in the total for Store 1. The goal is for this example to provide a single result of 360.
I think the correct implementation would involve some sort of join which retrieves the Store ID from stores by using IFNULL to get either the canonical_id or id after selecting based on id from the items table, but I'm struggling to implement a solution that works.
Any pointers would be greatly appreciated, thank you.
Edit: my attempt is as follows, it appears to meet my needs, are there any caveats / issues with my approach?
SELECT SUM(price) as `stock_value`, IFNULL(stores.canonical_id, store_id) as `store`
FROM items
JOIN stores on stores.id = items.store_id
GROUP BY store
I just realize you don't wanted to keep the stock_values of the "children" or "related" stores. However the next approach take those into account too:
SELECT
s.*,
(SELECT
SUM(i.price)
FROM
items AS i
INNER JOIN
stores AS s1 ON s1.id = i.store_id
WHERE
s1.cannonical_id = s.id
OR
s.id = i.store_id) AS "stock_value"
FROM
stores AS s
Online example: DB-Fiddle
If you don't want they, you just could filter the previous query using the condition WHERE s.cannonical_id is NULL like this:
SELECT
s.*,
(SELECT
SUM(i.price)
FROM
items AS i
INNER JOIN
stores AS s1 ON s1.id = i.store_id
WHERE
s1.cannonical_id = s.id
OR
s.id = i.store_id) AS "stock_value"
FROM
stores AS s
WHERE
s.cannonical_id is NULL
But, you should note that the query you posted on the updated question will be better in performance than this approach.

Mysql trigger that multiplies two values from different tables, totalizes by groups and adds values to another column

I've been going around this for a while and there isno way I can figure it out. Let's say I have these three tables:
Users
Name | Basket value
-------+---------------
John | ???
-------+---------------
Pierre | ???
Items
User | Item | Amount
-----------+------------+------------
John | Pears | 2
-----------+------------+------------
Pierre | Pears | 1
-----------+------------+------------
Pierre | Apples | 3
Market_ prices
Item | Price
------------+---------------
Pears | 2.35
------------+---------------
Apples | 2.56
Basket value is needed. So for each row in ITEMS it must multiply its AMOUNT by MARKET_PRICES[PRICE] and sum all the results grouped by USER and place this result in USERS[total items value]. But how could the syntax be elaborated to take this to practice?
Many thanks in advance for the help.
One approach is to join the relevant tables:
SELECT u.name, SUM(i.amount*m.price)
FROM users u
JOIN items i ON u.name = i.user
JOIN market_prices m ON i.item = m.item
GROUP BY u.name;
(SQLfiddle of this is at: http://sqlfiddle.com/#!9/ec224/6 - I added a few other rows to the tables to test more complexity, so the totals aren't what you'd get from your example. Specifically, I added Bananas 3.75 to the Market_prices table and John Apples 3 and Pierre Bananas 5 to the Items table.)
The goal here is to link the information in all three tables through shared fields (via the JOIN), while also GROUPing and creating a SUM of the calculated costs as a product of market price and number of items.
---- edited based on comments ----
To do this as an update, you could try:
UPDATE users
SET basket_value = (SELECT basket FROM
(SELECT name, SUM(i.amount*m.price) AS basket
FROM users u JOIN items i ON u.name = i.username
JOIN market_prices m ON i.item = m.item
GROUP BY u.name) q1 WHERE q1.name = users.name);
I have a feeling there is a more elegant solution, but this works. Modified SQLFiddle is: http://sqlfiddle.com/#!9/56245a/1
SELECT User, SUM(rev) AS basket_price
FROM
(
SELECT a.User AS User, a.Amount*b.Price AS rev
FROM Items a
LEFT JOIN
Market_Prices b
ON a.Item = b.Item
) a1
GROUP BY User

MySQL double group

I am making queries to extract data from database which holds customer order. There's one table which holds customer id's and the customer's name. Another table which has the order id, customer id of who placed the order, a quantity of the item bought, and an item id. The last table holds the item id's and item names. I am trying to sort these to show an individual's most popular purchase, but am having issues properly grouping and ordering to produce the correct result, below is an example of what is intended.
customers
1 | John
---+-----
2 | Jane
orders
1 | 2 | 4 | 1
---+---+---+---
2 | 2 | 5 | 2
---+---+---+---
3 | 2 | 2 | 1
---+---+---+---
4 | 1 | 1 | 2
items
1 | Chair
---+-------
2 | Sofa
After properly sorting and grouping, the output table should like:
John | Sofa
------+------
Jane | Chair
Currently I can connect the item names to the purchaser and return a random item bought, but not the most popular by quantity. I have tried entering multiple fields into group by and managed to properly group the items by name and sort by quantity, but in doing so the customer id's became ungrouped. Been trying to solve this for days so any help would be appreciated. Please note that this is a very simplified version of the actual problem where many more tables are involved, including multiple items table which are being joined together to one.
You should use group by on joined tables
select
b.name
, c.name
, sum(quantity) as tot
from orders as a
inner join Customers as b on a.customer_id = b.id
inner join Items as c on a.item_id = c.id
group by b.name, c.name
order by tot
Selecting the sum of the quantities per customer-item group is easy, but selecting the top seller is a bit harder.
The first step is the query to get all the groups with the sums of the quantities for each customer-item:
SELECT
customer_name,item_name,SUM(quantity)
FROM
orders o
JOIN customers c ON o.customer_id=c.id
JOIN items i ON o.item_id=i.id
GROUP BY customer_name,item_name;
Then to only select the groups with the maximum quantity sums we use some trickery:
SELECT
customer_name,item_name,SUM(quantity),
(SELECT SUM(quantity) AS qmax
FROM
orders o2
JOIN customers c2 ON o2.customer_id=c2.id
JOIN items i2 ON o2.item_id=i2.id
WHERE c2.id=c.id
GROUP BY c2.customer_name,i2.item_name
ORDER BY qmax DESC LIMIT 1) AS qmax
FROM
orders o
JOIN customers c ON o.customer_id=c.id
JOIN items i ON o.item_id=i.id
GROUP BY customer_name,item_name
HAVING SUM(quantity)=qmax;
Edit:
Here's a link to a fiddle: SQLFiddle