Is it possible to create mutiple MySQL queries within the same table? - mysql

Is it possible to make multiple queries at once within the same query?
Here is an example of what I'm trying to do.
We have the following table:
| userid | price | stock | description |
----------------------------------------
1 10.00 5 some text
2 25.00 2 some text
3 15.00 3 some text
4 35.00 2 some text
5 30.00 4 some text
The queries that I'm trying to do are:
the MIN and MAX price group by description
the price set by userid 2
Stock and price of the first three results only without grouping
So the HTML table will look like this:
description | Min_Price | Max_Price | Price Set by userid 2 | 1st Price | 1st Stock | 2nd Price | 2nd Stock | 3rd Price | 3rd Stock

This solution will require a number of "sub queries" or joins.
You are probably looking at something like:
select t1.description,
t1.min_price,
t1.max_price,
t2.user_id_2_price
from
(select description, min(price) as min_price, max(price) as max_price from t group by description) t1
left join
(select price, description as user_id_2_price from t where userid = '2') t2
on
(t1.description = t2.description)
And you can add as many of these "left joins" as you need

MySQL Unions (http://dev.mysql.com/doc/refman/5.0/en/union.html) should probably put you on the right track.
You could also do most of it with sub selects, though that is probably not a great idea.

Use union or, to have everything in one row, something like that:
Select
(Select min(price) from table) as min_price,
(Select max(price) from table) as max_price,
....

Related

Getting all entries less than max price and more than one entry from having

I'm using the Northwind database from W3 schools and my query is
SELECT Price from products group by Price having Price < max(Price)
It's currently showing no results, but how would I fix that? You can see the database here: https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_having
Additionally, is it possible to get more than one entry returned from having, i.e, all rows that meet the having clause condition. For example, in the link above, only unique countries are returned that meet the condition.
EDIT: Also with the Northwind database:
SELECT *FROM Customers GROUP BY City HAVING COUNT(City) > 2;
Why does it have unexpected behaviour, i.e, not return the rows where there are more than two occurrences of the city.
try like below
SELECT Price from products
where Price < (select max(Price) from products)
if you add the max(price) to the select
DROP table if exists t;
create table t
(price int);
insert into t values (1),(2),(1),(2),(3),(10);
SELECT Price, max(price) mp from t group by Price;
you get
+-------+------+
| Price | mp |
+-------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 10 | 10 |
+-------+------+
4 rows in set (0.001 sec)
the having test is on the grouped items and is never true . To produce the correct result you need the sub query suggested by #akina.

MySQL: How to have sum of each column for many columns

I have a table like this:
client_id | Product1 | Product2 | ... | Product170
--------------------------------------------------
4 | Null | 4 | ... | 5
32 | 5 | 3 | ... | Null
22 | 4 | 1 | ... | 3
I want to have the totals for each of my Products. I want a view, or something similar, like this:
product_id | Total
--------------------------------------------------
Product1 | 9
Product2 | 8
...
Preferably leaving out Products that have a sum of 0.
Am I able to do this? I have many columns so I would rather not have a SELECT statement calling each individual column by name.
(Context: This table holds orders for a business. A client will order some products and it is stored here. If you have a better way to organize this info, please let me know).
Am I able to do this?
Yes, by writing an extremely long query with UNION.
Example:
SELECT 'Product1' as product_id, SUM(Product1) as Total
FROM table
UNION
SELECT 'Product2' as product_id, SUM(Product2) as Total
FROM table
UNION
...
Obviously this is not practical, so...
If you have a better way to organize this info, please let me know
A better way to organize this info would be to normalize it using a products table (with a unique id) and a junction table (e.g. client_products). This table contains 3 columns : client_id, product_id and n (the number of product, or whatever your number represents). The primary key is (client_id, product_id), and add an index to product_id.
You can very easily query this model with SELECT product_id, SUM(n) FROM client_products GROUP BY product_id.
You can write the query like
SELECT sum(Product1) as Product1, sum(Product2) as Product1 FROM `product`
It will give you the total of each product but in one row and having product name as column. You can also add the > 0 condition in where clause

SQL, Find orders where strict critera is met, Match item, not if other items purchased

I have stumped all the IT people at my work with this one, so wondeirng if anyone can help.
I need to extract from an order table anyone who has only purchased a specific product type, (if they have order the product type and any other product types i dont want to know who you are)
for example the table is roughly
---------------------------------------------------------------------------------------
Order ID | item code | Name |
----------------------------------------------------------------------------------------
1 | ADA | item 1
2 | ADA | item 1
2 | GGG | item 2
3 | ADA | item 1
----------------------------------------------------------------------------------------
So i want to find all the order IDs of people who only purchased item code ADA, BUT not if they purchased over items, so the output of this query should be order ID 1 & 3 and skipping order 2 as this had a different item.
Would really appriciate it if anyone could help.
Assuming an order can't have multiple records with the same ItemCode, you could use:
SELECT *
FROM Orders
WHERE OrderID IN (
SELECT OrderID
FROM Orders
GROUP BY OrderID HAVING COUNT(*) = 1
)
AND ItemCode = 'ADA'
If an order could have multiple records with the same ItemCode then you'd have to change the SELECT * to SELECT DISTINCT * and then COUNT(*) to COUNT(DISTINCT ItemCode)
Based on your current explanation and example, the below should work. However, there are outstanding questions in the comments which may change the actual correct solution.
SELECT
O.OrderId, MAX(itemCode), MAX(Name)
FROM
Orders O
INNER JOIN
(SELECT
OrderId
FROM
Orders
WHERE
itemCode = 'ADA') ADA
ON
O.OrderId = ADA.OrderId
GROUP BY
O.OrderId
HAVING
COUNT(*) = 1

select min value of a field from joins table

CREATE VIEW products_view
AS
Hi guys ! I've tree tables:
Products
Categories
Prices
A product belongs to one category and may has more prices.
consider this set of data:
Product :
id title featured category_id
1 | bread | yes | 99
2 | milk | yes | 99
3 | honey | yes | 99
Price :
id product_id price quantity
1 | 1 | 99.99 | 10
2 | 1 | 150.00 | 50
3 | 2 | 33.10 | 20
4 | 2 | 10.00 | 11
I need to create a view, a full list of products that for each product select the min price and its own category.
eg.
id title featured cat.name price quantity
1 | bread | yes | food | 99.99 | 10
I tried the following query but in this way I select only the min Price.price value but Price.quantity, for example, came from another row. I should find the min Price.price value and so use the Price.quantity of this row as correct data.
CREATE VIEW products_view
AS
SELECT `Prod`.`id`, `Prod`.`title`, `Prod`.`featured`, `Cat`.`name`, MIN(`Price`.`price`) as price,`Price`.`quantity`
FROM `products` AS `Prod`
LEFT JOIN `prices` AS `Price` ON (`Price`.`product_id` = `Prod`.`id`)
LEFT JOIN `categories` AS `Cat` ON (`Prod`.`category_id` = `Cat`.`id`)
GROUP BY `Prod`.`id`
ORDER BY `Prod`.`id` ASC
My result is:
id title featured cat.name price quantity
1 | bread | yes | food | 99.99 | **50** <-- wrong
Can you help me ? Thx in advance !
As documented under MySQL Extensions to GROUP BY (emphasis added):
In standard SQL, a query that includes a GROUP BY clause cannot refer to nonaggregated columns in the select list that are not named in the GROUP BY clause. For example, this query is illegal in standard SQL because the name column in the select list does not appear in the GROUP BY:
SELECT o.custid, c.name, MAX(o.payment)
FROM orders AS o, customers AS c
WHERE o.custid = c.custid
GROUP BY o.custid;
For the query to be legal, the name column must be omitted from the select list or named in the GROUP BY clause.
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. This means that the preceding query is legal in MySQL. You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values within each group the server chooses.
What you are looking for is the group-wise minimum, which can be obtained by joining the grouped results back to the table:
SELECT Prod.id, Prod.title, Prod.featured, Cat.name, Price.price, Price.quantity
FROM products AS Prod
LEFT JOIN categories AS Cat ON Prod.category_id = Cat.id
LEFT JOIN (
prices AS Price NATURAL JOIN (
SELECT product_id, MIN(price) AS price
FROM prices
GROUP BY product_id
) t
) ON Price.product_id = Prod.id
ORDER BY Prod.id

sort sold table by most frequent product_id

hi i have a sold table in my db , my table looks like this :
+-----------+---------------------+---------+---------+
| id | product_id | user_id | date |
+-----------+---------------------+---------+---------+
| 1 | 20 | 2 |392185767|
+-----------+---------------------+---------+---------+
| 2 | 28 | 3 |392333337|
+-----------+---------------------+---------+---------+
i want to want to sort table output by most purchased products
something like :
$sql = "select * from sold order by most_repeated(product_id)";
i don't want to group the out put by product id , i just want to sort them so the most repeated products shows at the top of result
Since you do not want to group by, you could use a correlated query:
select * from sold s
order by (select COUNT(1) from sold ss where ss.product_id=s.product_id)
I have not tried this in MySQL, but it should work.
You simply cannot find the repeated products without counting it.
SELECT product_id, COUNT(product_id) AS product_count
FROM sold
GROUP BY product_id
ORDER BY product_count DESC;
This query should give you what you want without having to count the same product multiple times.
select s.*
from sold s join
(select count(product_id) as times_purchased, product_id
from sold
group by product_id) most_repeated on s.product_id = most_repeated.product_id
order by most_repeated.times_purchased
Good Luck!