select all rows with lowest product_id - mysql

i have this table and i want to select all rows with product id 105. i can easily do this if i know product id and put in where clause but i dont know product id and it increases once this id work is completed it will delete these rows and search for next lowest product id.
with order bt product_id i can do but how to ensure that all rows are listed. if i will give 100 limit then first 10-15 may be lowest after that it will start listing next higher product_id rows
here is table
id name product_id some_columns
1 dff 105 gfff
2 fg 109 ffgfgf
3 tt 106 gttytt
4 tt 105 trtr
5 trr 112 trrrt
6 rrr 111 rttttr
7 ttyt 108 ttrtrtr
8 rrrr 105 rrerer
SELECT id, name, product_id, some_columns
FROM table_name
WHERE product_id = (SELECT MIN(product_id) FROM table_name)
here you can see that lowest product_id is 105 but i dont have any control on how many times it will appear in table. in some case it may be 10 rows and in some case it may be 250 rows.
so order by product_id will not work. as giving limit will list all id initial few rows may be 105 but after than when all 105 rows are listed it will start listing all rows which is higher than 105
the best solution would be if i could use where product_id=105 but my bad luck i dont have any control on product id so cant use product id in where clause. next big problem is i want to use it efficiently so we have indexed product_id column
i was exploring min value option but i am highly doubtful about its efficiency and probable affect on mysql
so any help will be great

You can try something like
SELECT id, name, product_id, some_columns
FROM table_name
WHERE product_id = (SELECT MIN(product_id) FROM table_name)
As far as I understood you want to select all the rows that match the minimum product_id. Be it 101, 102 or whatever, it's uncontrollable, so you get the minimum product_id in the row and then you select the rows that has the current minimum product_id.

You could try using a subquery for min_id group by product
select m.*
from table_name m
inner join (
select min(id) min_id, product_id
from table_name
group by product_id
) t on t.min_id = m.id

Related

Select Min and Max value

I have a table called 'customers':
id | name | age
1 | john | 35
2 | paul | 22
3 | ana | 26
4 | mark | 19
5 | jack | 29
i want to select the name and max age, the name and min age... something like:
john 35 mark 19
is it possible?
The below query will give you the min and max on one row as requested. If there are multiple matches for min/max you will get multiple rows. Depending on the SQL engine you use, the syntax to limit to one row is different.
SELECT cMax.Name, cMax.Age, cMin.Name, cMin.Age
FROM customers cMin
JOIN customers cMax ON
cMax.Age = (SELECT MAX(Age) FROM customers)
WHERE cMin.Age = (SELECT MIN(Age) FROM customers)
There are different types of joins (e.g. INNER, OUTER, CROSS); however, for your question it doesn't much matter which you use.
Yes, you can do it,
select name, age from customers
where age in (select max(age)
from customers union select min (age)from customers)
try this
select name, age from customers where age=(select max(age) from customers) union
select name, age from customers where age=(select min(age) from customers)
If you want them on the same row:
select cmin.*, cmax.*
from (select name, age as minage
from customers
order by age asc
fetch first 1 row only
) cmin cross join
(select name, age as maxage
from customers
order by age desc
fetch first 1 row only
) cmax;
fetch first 1 row only is standard syntax for returning only the first row of the result set. Some databases have bespoke syntax, such as limit or select top (1).
Try using this query to show MAX age:-
select * from customers where age=(select max(age) from customers);
To show MIN age use the below Query:-
select * from customers where age=(select min(age) from customers);
You could use a cross join, which will put the two query ouputs next to one another. Building off Rodrigo's queries:
select
max_cust.name,
max_cust.age,
min_cust.name,
min_cust.age
from (select name, age from customers where age=(select max(age) from customers)) as max_cust
cross join (select name, age from customers where age=(select min(age) from customers)) as min_cust
It's maybe not the most performant but it gets the right shape. Be wary of cross joins when the tables don't have exactly 1 row, as it creates a cartesian product of the rows in the tables being joined.

Remove records from two tables when value bases on dependancy

In my Opencart shop I have a lot of products with an option for color and size.
Sometimes due to importing from excel, the color option only was one value e.g. white.
I want to remote all options where the optionvalue only has one choice.
The information is stored into two tables: oc_product_option_value and oc_product_option.
For example in oc_product_option_value this looks like this:
product_id option_id
--------------------
66 18
66 18
66 17
67 18
67 18
67 17
So I want need to remove one time 66 with option 17 and one time 67 with option 17.
When I use:
select * from oc_product_option_value group by product_id, option_id having count(*) = 1
It gives me all the product_id's with only one optionvalue and I can remove it.
But I also need to remove the same product_id's from table oc_product_option.
How can I select all the products in oc_product_option which only have one optionvalue in oc_product_option_value.
I tried this but it isn't working:
select * from oc_product_option
where option_id IN (select product_id from oc_product_option_value group by product_id, option_id having count(*) = 1)
Try this in for option_id:
select oc.* from oc_product_option oc
INNER JOIN (
select option_id,product_id from oc_product_option_value group by product_id, option_id having count(*)=1
) t on t.option_id=oc.option_id AND t.product_id =oc.product_id
OK this bring me a little closer:
select * from oc_product_option where product_id in (select product_id from oc_product_option_value group by product_id, option_id having count(option_id) = 1)
This gives me all the correct product_id BUT show me the product_id with all the option_id's. Not just the ones that are single.

SELECT DUPLICATE MAX(ID)

I have data similar to the following in my table:
id territory_id platform_id title_id other columns
1 US ITUNES 155 10 others columns...
100 US ITUNES 155 10 others columns...
101 FR ITUNES 155 10 others columns...
I need to SELECT MAX(ID) on all duplicate rows, based on (territory_id, platform_id, title_id).
The query on the above data set should return the id 100, since the only duplicate above based on (territory_id, platform_id, title_id) is ('US', 'ITUNES', 155) and the MAX(ID) of that duplicate entry is 100 (not 1).
How would I build this query? So far I have:
SELECT id FROM table GROUP BY territory_id, platform_id, title_id
You can GROUP BY the 3 fields, then using HAVING clause you can identify duplicates. Using MAX you can get the max ID for each of those groups having duplicates:
SELECT MAX(ID), territory_id, platform_id, title_id
FROM MyTable
GROUP BY territory_id, platform_id, title_id
HAVING COUNT(*) > 1
SQL Fiddle Demo
I think you are looking for something like this
select DISTINCT territory_id, max(ID)
,platform_id,title_id
from test t
GROUP BY territory_id,platform_id,title_id
HAVING COUNT(*)>1
Here are the results from the replicated table
territory_id id platform_id title_id
US 100 ITUNES 155
If you needed to you could go one step further and declare a variable if this will make its way to a report.

SQL query distinct with additional select

I need to perform a query in MySQL that returns distinct values for product_id but also I need to select and return 'id' field which is in that particular table.
This query will return distinct product_id's without id:
SELECT DISTINCT product_id FROM orders_cart
This query will use distinct on both fields which and I want to use it on product_id and see the id
SELECT DISTINCT id, product_id FROM orders_cart
It would be quite easy to do on pgsql but I have no idea how to do this on mysql.
Your query is not well-defined: Consider this table
id product_id
1 1
2 2
3 1
4 2
What should your query result be? If you mean
id product_id
1 or 3 1
2 or 4 2
you are in the land of non-deterministic queries.
What you could do is
SELECT MIN(id), product_id FROM orders_cart GROUP BY product_id
which would deterministically produce
id product_id
1 1
2 2
Thats my final code:
The most important bits for this issue were line 1,2 and 4 :)
GROUP BY did the trick :)
SELECT orders_cart.id, product_id, order_id
FROM orders_cart
LEFT JOIN orders_order ON orders_cart.order_id=orders_order.id
WHERE orders_order.status='Wysłano'
GROUP BY orders_cart.product_id

Count the same order_id and output how many in SQL

I would like to count how many rows there is of the same order_id in the table refnumbers
So it should output:
There's 5 rows with the order_id 123
There's 9 rows with the order_id 124
There's 18 rows with the order_id 125
There's 2 rows with the order_id 77
It's the column order_is that it should counter after in the table refnumbers
I dont really know how to do this without specifically mention a order_id and then do a loop through them in php.
You need to use group by on the column that you want to get the count for.
This does not work
SELECT count(*) as rowcount
FROM refnumbers
Will give you a single row with all rowcounts
Count per distinct order_id
SELECT order_id, count(*) as rowcount
FROM refnumbers
GROUP BY order_id /*WITH ROLLUP*/
ORDER BY order_id
Will give you the count per distinct order_id.
If you want to get the total count as well uncomment the with rollup part.