3 tables to count the item price - mysql

i have 3 tables to count the item price, and i need to know total of spent too,
table data
id
name
1
data
2
data2
detail
id
data id
item
price
1
1
bag
2000
2
1
chair
2000
table spent
id
detail id
spent
1
1
200
2
1
200
expected result
-> data | 4000 | 400

SELECT data.name, d.price, s.spent
FROM data
JOIN ( SELECT data_id id, SUM(price) price
FROM detail
GROUP BY id ) d USING (id)
JOIN ( SELECT detali_id id, SUM(spent) spent
FROM spent
GROUP BY id ) s USING (id)

Related

SQL query to only yield multiple occurances

I am using mariadb and I have a table called links:
id | product_id | last_change
------------------------------
1 1 xxx
2 2 xxx
3 5 xxx
4 5 xxx
I want to find every object (3, 4 in this example) that occures more than once. Following this answer I tried:
SELECT product_id, COUNT(*) from links HAVING COUNT(*) > 1
But this results in the (adapted to this example) first row being shown and the total number of product_id occurrences:
product_id | COUNT(*)
---------------------
1 4
I wanted to achieve a list of all items occuring more than once:
id | product_id | last_change
------------------------------
3 5 xxx
4 5 xxx
An aggregation function without GROUP BY always results in only one row result as it aggregates all rows
So use a GROUP BY
SELECT product_id, COUNT(*) from links GROUP BY product_id HAVING COUNT(*) > 1
To see all entry with the count of the product_id , you can do following
SELECT l1.product_id , last_change , Count_
FROM links l1
JOIN (SELECT product_id, COUNT(*) as Count_ from links GROUP BY product_id HAVING COUNT(*) > 1) l2
ON l1.product_id = l2.product_id
Try below statement
select id, product_id, count(product_id)
from links
group by (product_id)
having count(product_id)> 1;

SQL get rows based on two ids

I really don't know how to title this problem properly.
Heres the table structure:
ID | CLIENT_ID | …
ID is primary and auto increment. CLIENT_ID on the other hand can occur multiple times.
What i want is to fetch the rows by CLIENT_ID with highest ID ... Heres a example
ID | CLIENT_ID
1 | 1
2 | 1
3 | 2
4 | 3
5 | 2
So here CLIENT_ID 1 and 2 occurs multiple times (because there is a newer version).
After the query i want the following IDs in the results: 2,4,5 (Because the highest ID in rows with CLIENT_ID 1 is the row with ID 2 and so on)
If you need all the columns you can use a select in
select * from my_table
where (id, client_id) in ( select max(id), client_id
from my_table
group by client_id);
but if you need only the id
select id from my_table
where (id, client_id) in ( select max(id), client_id
from my_table
group by client_id);
or more simple
select max(id)
from my_table
group by client_id;
SELECT * FROM table GROUP BY client_id HAVING max(id)
this should be more efficient than a sub select

Query: getting the last record for each member trouble cause by another value

i have data below for example
id product_id date
------ ---------- ----
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 2
7 3 1
result data query that i want "the last record of last date on each product_id"
to get it that result i use the query like below
SELECT a.* FROM test AS a
JOIN (SELECT MAX(id) AS id, product_id, MAX(DATE) AS DATE FROM test GROUP BY product_id) AS b
ON a.id = b.id AND a.product_id = b.product_id AND a.date = b.date
this time i got what i want as the result
id product_id date
------ ---------- --------
3 1 3
6 2 2
7 3 1
my problem when i add another data like below
id product_id date
------ ---------- --------
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 2
7 3 1
8 1 3
9 1 2
and use the same query the result become like this
id product_id date
------ ---------- --------
6 2 2
7 3 1
where the the value '1' for product_id?
Try this
SELECT id, product_id, DATE FROM test sitem WHERE product_id IN (1,2,3) AND DATE = (SELECT DATE FROM test WHERE product_id =
sitem.product_id ORDER BY DATE DESC LIMIT 1) AND id =
(SELECT id FROM test WHERE product_id = sitem.product_id ORDER BY DATE DESC,
id DESC LIMIT 1) GROUP BY product_id
This is your subquery:
SELECT MAX(id) AS id, product_id, MAX(DATE) AS DATE
FROM test
GROUP BY product_id
It is independently calculating the maximum of id and date. But, there is no guarantee that these two values are in the same record. There are ways to fix the subquery, but they are rather complicated.
Instead, I would suggest using an alternative method to get the last record:
SELECT t.*
FROM test t
WHERE NOT EXISTS (SELECT 1
FROM test t2
WHERE t2.product_id = t.product_id AND
(t2.date > t.date OR
t2.date = t.date AND t2.id > t.id
);
This identifies the last record for each product as the one where no other record has a larger date. And, if two records have the same date, no other record has a larger id.

MYSQL SUM() in one table and JOIN with 2 other tables

I have 3 tables: items, purchases, and collaborators. A user can own an item, purchase an item, or be a collaborator on an item. Additionally, items that are purchased can be rated up, +1, or down, -1. An owner or collaborator can't purchase their own item.
I'd like to get all items for a given user and also display the ratings on each item.
Here's my tables:
items | purchases | collaborators
i_id item_id user_id | p_id item_id user_id rating |c_id item_id user_id
1 1 11 | 1 1 13 -1 | 1 1 12
2 2 12 | 2 2 11 1 | 2 2 13
3 3 13 | 3 3 12 NULL |
| 4 1 14 -1 |
Here's my MYSQL query so far:
select *, count(p_id) as tots, sum(rating=1) as yes, sum(rating= '-1') as no
from items
left join purchases
on items.item_id=purchases.item_id
left join collaborators
on items.item_id=collaborators.item_id
where items.user_id=13 or purchases.user_id=13 or collaborators.user_id=13
group by items.item_id
Here's my expected results for user_id=11 (changing each user_id in the WHERE clause):
item_id tots yes no
1 2 0 2
2 1 1 0
// notice how user_id=11 doesn't have anything to do with item_id=3
Here's my expected results for user_id=12:
item_id tots yes no
1 2 0 2
2 1 1 0
3 1 1 0
Here's my expected results for user_id=13:
item_id tots yes no
1 2 0 2
2 1 1 0
3 1 1 0
//notice user_id=13 should have same results as user_id=12. Although, their
relation to each of the 3 items is different, they still either purchased,
own, or collaboratored on each of them.
Unfortunately, I get the first two results but not the correct one for user_id=13.
For user_id=13, item_id=1 the tots=1 and not tots=2 for some reason I can't understand.
Any thoughts, such as, "its better to separate this into 2 queries", would be greatly appreciated,
I'm still not entirly sure I understand you correct but you could try following statement and let us work from there.
Edit
Following statement returns the expected results.
You can verify this (using SQL Server) here.
The gist of this is to
select all possible user_id and item_id combinations from your three tables
select the counts/ratings for each item
combine the results
SQL Statement
SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no
FROM (
SELECT user_id, item_id, title FROM items
UNION SELECT user_id, item_id, NULL FROM purchases
UNION SELECT user_id, item_id, NULL FROM collaborators
) u INNER JOIN (
SELECT COUNT(*) AS cnt
, SUM(CASE WHEN ISNULL(rating, 1) = 1 THEN 1 ELSE 0 END) AS yes
, SUM(CASE WHEN rating =-1 THEN 1 ELSE 0 END) AS no
, item_id
FROM purchases
GROUP BY
item_id
) pt ON pt.item_id = u.item_id
MYSQL statement
SELECT u.user_id, pt.item_id, pt.cnt, pt.yes, pt.no, u.title
FROM (
SELECT user_id, item_id, title FROM items where user_id=13
UNION SELECT user_id, item_id, NULL FROM purchases where user_id=13
UNION SELECT user_id, item_id, NULL FROM collaborators where user_id=13
) u INNER JOIN (
SELECT COUNT(*) AS cnt
, SUM(rating=1) AS yes
, SUM(rating =-1) AS no
, item_id
FROM purchases
GROUP BY
item_id
) pt ON pt.item_id = u.item_id

SQL Counting sums of rows

I have 2 tables.
Table 1: Fruits
id (int, autoincreasing, primary key)
some other junk
Table 2: Customers
has a 'fruit' column, this column contains an id from the fruit table.
i want to query all the customers, and come up with a list of all the fruit ID's and the number of times they are in use.
So this set up:
Fruits has
id name
1 orange
2 banana
3 apple
Customers has 6 rows like:
id fruit
1 1
2 1
3 2
4 2
5 2
6 3
Trying to write a query that Will give me:
fruit id purchase count
1 2
2 4
3 1
Try this
SELECT f.id as fruit_id, COUNT(1) AS purchase_count
FROM FRUITS f LEFT JOIN CUSTOMERS c
ON F.ID = c.fruit
GROUP BY f.id
Should just be a simple aggregate...
SELECT fruit_id, COUNT(fruit_id) AS purchase_count
FROM customers
GROUP BY fruit_id
ORDER BY fruit_id ASC;
untested
SELECT id, SUM(fruit) as "fruit id", "purchase count"
FROM Customers
GROUP BY id;