We require to get row if product_id is in sequence.
Table (product)
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
6 Nuts
8 Britania
9 Pepsi
Require Output
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
6 Nuts
product_id - 8 and 9 not getting because it is not in sequence.
My Try
select distinct t1.*, t1.product_id, (select GROUP_CONCAT(t2.product_id) from product as t2) as p_id
from product t1
having FIND_IN_SET(t1.product_id+1, p_id)
Output
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
In this try i am not getting product_id - 6 row.
Note : I want MySql query not in PHP.
Thank You !
One way i can think of is to user user defined variable to get the rank of row and then calculate the difference of product id and rank and select only those rows where difference = 0
select *
from(
select f.*,#row:= #row + 1 rank,
product_id - #row as diff
from product f,
(select #row:= 0) t
order by product_id
) t1
where diff = 0
Demo
Or if you want to pick the least sequence no. automatically you can write it as
select *
from(
select f.*,#row:= #row + 1 rank,
product_id - #row as diff
from product f,
(select #row:= (select min(product_id) from product_sale_flag) a) t
order by product_id
) t1
where diff = -1
Demo
Explanation
First query assign's minimum value of product_id to variable #row,then it assigns a rank to each row ordered by product_id in ascending order, once rank is assigned for every row then it calculates the difference between the original value of product_id and lastly using the resultant difference it checks where difference is 0 get those rows because they follow the sequence. Hope this makes sense
Related
Q : I am trouble to do following task in mysql query.
Task is get all products (If product is duplicate than sum of it's qty) and deduct wastage stock (If wastage product is duplicate than sum of it's qty).
I have two tables like,
1) manage_stock
2) manage_wastage
manage_stock
=> This table has p_id(Product ID) and many rows with product duplication's.
p_id p_name p_qty
1 Pro-1 10
2 Pro-2 15
3 Pro-3 8
1 Pro-1 15
manage_wastage
=> This table has p_id(Product ID) of manage_stock table. It is also many rows with product duplication's.
p_id w_qty
1 2
1 4
3 5
Desired Output
p_id p_name p_qty w_qty final_qty
1 Pro-1 20 6 14
2 Pro-2 15 0 15
3 Pro-3 8 5 3
Thank you very much.
You just have to compute the difference between the stock quantity and the wastage
SELECT s.p_id, s.p_name, SUM(p_qty), SUM(w_qty), SUM(p_qty) - SUM(w_qty) as final_qty
FROM manage_stock s
LEFT OUTER JOIN manage_wastage w
ON s.p_id = w.p_id
GROUP BY s.p_id, s.p_name
try this one
SELECT s.p_id, s.p_name, SUM(p_qty),SUM(ifnull(w_qty, 0)),SUM(p_qty - ifnull(w_qty, 0)) as total
FROM manage_stock s
left outer JOIN manage_wastage w
ON s.p_id = w.p_id
GROUP BY s.p_name
its work
SELECT ms.p_id ,GROUP_CONCAT(ms.p_name)p_name ,SUM(ms.p_qty) p_qty ,SUM(mw.w_qty) w_qty,SUM(ms.p_qty)-SUM(mw.w_qty) final_qty FROM manage_stock ms
INNER JOIN manage_wastage mw on ms.p_id =mw.p_id
GROUP BY ms.p_id
Try above code.
As p_name always unique with p_id GROUP_CONCAT() only returns single name.
I am trying to retrieve the minimum price of some models.
Each model belongs to a certain group which belongs to a product.
I have the following tables:
Product
model_id product_id price
1 1 100
2 1 120
3 1 100
4 1 200
5 1 250
10 1 20
11 1 50
12 1 50
Product Overview
model_id product_id group_id
1 1 A
2 1 A
3 1 A
4 1 A
5 1 A
10 1 B
11 1 B
12 1 B
Product Group Optional
group_id product_id
B 1
Some groups could be optional, which means price will be zero unless the member wants to choose otherwise.
So in the example above, I want to get the sum of minimum price from each group.
We have two groups, group A and group B.
Group A minimum price value is 100 (model_id 1 and 3)
Group B minimum price value is 20 (model_id 10) but because Group B is optional then that means minimum price value is 0.
Overall sum of min values: 100 (Group A) + 0 (Group B) = 100
My code so far:
SELECT po.group_id,
CASE WHEN
((SELECT COUNT(*) FROM product_group_optional pgo
WHERE po.group_id = group_id AND po.product_id = 1 AND po.product_id = product_id) >= 1)
THEN SUM(0)
ELSE SUM(p.price)
END AS sum_price
FROM product_overview po, product p
WHERE po.product_id = 1
AND po.model_id = p.model_id
AND p.price = (
SELECT MIN(p2.price)
FROM product p2, product_overview po2
WHERE po2.product_id = 1 AND po2.group_id = po.group_id
AND po2.model_id = p2.model_id
)
GROUP BY po.group_id
The output:
group_id sum_price
A 200
B 0
The problem is that I get 200 for Group A but it should be 100.
There are 2 models with min value 100, model 1 and 3. And I assume these are sum together = 100 + 100 = 200.
Issue a) But I want to just take the min value, no matter how many times this value exists.
Issue b) Also, I am trying to get the SUM of those two output SUM of Group A and Group B.
But I am not sure how to do it.
I want it to be done in this query.
Desired output
Sum of all groups
100
Can anyone lead me to the right direction please?
You can use the following query:
SELECT SUM(min_price)
FROM (
SELECT po.group_id,
MIN(CASE WHEN pgo.group_id IS NULL THEN price ELSE 0 END) AS min_price
FROM Product AS p
INNER JOIN Product_overview AS po
ON p.product_id = po.product_id AND p.model_id = po.model_id
LEFT JOIN Product_group_optional AS pgo ON po.group_id = pgo.group_id
GROUP BY po.group_id) AS t
I'm not sure that I understand the keys of your tables, and the problem as well.
There is few questions.
a) The answer should be 120?
b) If the Product has no price, the is price null?
c) If there is a Product in a group with null price and others with price, should it be counted as 0?
Here is how you could get the sum of the lower prices of each group, ignoring the product_group_optional for while:
SELECT t2.group_id, sum(t2.new_price)
FROM
(
SELECT t.group_id, t.new_price
FROM
(
SELECT po.group_id, if(ifnull(pgo.product_id, true), p.price, 0) as new_price
FROM product p, product_overview po
LEFT JOIN product_group_optional pgo ON po.group_id = pgo.group_id
WHERE p.model_id = po.model_id
ORDER by po.group_id, new_price
) t
GROUP BY t.group_id
) t2
I have a two MYSQL tables:
Table-1
id catid title user_rating
123 8 title-one 3
321 8 title-two 5
and
Table-2
listing_id title user_rating
123 title-one 3
321 title-two 5
Plus, I have this query that calculates the current rank of each "title" based on "user_rating".
SELECT
MAX(x.rank) AS rank
FROM
(SELECT
a.id,
a.catid,
a.title,
b.listing_id,
#rank:=#rank + 1 AS rank
FROM
`table-1` a
INNER JOIN `table-2` b ON a.id = b.listing_id
CROSS JOIN (SELECT #rank:=0) r
WHERE
catid = '8'
ORDER BY user_rating DESC) x
WHERE
id = 123
Now, my issue: I want to calculate the difference in "ranking" (rank) when I update the "user_rating" value.
Please, note: the "user_rating" value is updated by a php script that allow users to vote for a specific content (range 1 to 5, step 0.5).
What's the best way to get the difference between the "previous rank" and "current rank" after the update?
Thanks in advance to all.
This is kind of hard to explain so I'll break it down...Here's the objective
Suppose you have a table
ID | Weight
1 2
2 4
3 8
4 66
5 11
6 44
7 33
And suppose I have a set of interested IDs, say (3,4)
My objective is to get two other rows (one for each of the two interested IDs) such that the row that matches with the interested ID has a weight that is one level less than the weight of the interested ID
so in this case
for id 3, we want to return row with ID 2 and weight 4 since row id 2 is the first row of which the weight (4) is less than the weight of row id 3 (8)
for id 4, we want to return row with id 6 and weight 44 since row id 6 is the first row of which the weight (44) is less than the weight of row id 4 (66)
How would you accomplish this with mysql in one single query whereby we use the IN() notation for the interested IDs.....
I'd like to propose the following (used ourtable as table name obviously)
SELECT id,weight FROM ourtable WHERE weight IN (SELECT MAX(t.weight) FROM ourtable t,ourtable t2 WHERE t.weight < t2.weight && t2.id IN (3,4) GROUP BY t2.id);
it gives the following result
+----+--------+
| id | weight |
+----+--------+
| 2 | 4 |
| 6 | 44 |
+----+--------+
as requested.
You could solving this selecting the first row of a selection of the rows ordered by weight desc which weight is lower than the given weight, in this case for mysql something like:
select * from t where weight < (select weight from t where id = :id) order by weight desc limit 1
in a in statement following the idea above, you could have something like:
select * from (select id, (select weight from t where weight < (select weight from t where id = tp.id) order by weight desc limit 1) from t tp) a where id in (3,4)
Another solution w/o subquery:
select w1.id,w1.weight,
left(group_concat(w2.id order by w2.id desc ),LOCATE(',', group_concat(w2.id order by w2.id desc ))-1) as w2_id,
left(group_concat(w2.weight order by w2.weight desc ),LOCATE(',', group_concat(w2.weight order by w2.weight desc ))-1) as w2_weight
from weight as w1, weight as w2
where w2.weight < w1.weight
and w1.id in (3,4)
group by w1.id
I have this table
UMS
id_attribute value order
1 MB 1
1 Gb 2
1 TB 3
...
and this table
ATTRIBUTE_VALUE
id id_attribute value name ums
1 1 50 hdd GB
2 1 100 hdd TB
3 2 15.00 price NULL
and i want to select from ATTRIBUTE_VALUE where id_attribute=1 and if exist (UMS.value=ATTRIBUTE_VALUE.ums) then order by UMS.order end if group by ATTRIBUTE_VALUE.value
example for output :
50 GB
100 Tb
and must to appear
15.00 !!! here is the problem because in my UMS table i don't have UMS for price
but it doesn't appear
Update after you clarified your question - Try something like this:
SELECT T1.*
FROM ATTRIBUTE_VALUE T1
LEFT JOIN UMS T2
ON T1.id_attribute = T2.id_attribute AND T1.ums = T2.value
ORDER BY T2.order, T1.value
But note that this will fail if T1.value is greater than 1000. It might be better to convert all units to the same type before ordering them.
Result of query:
id id_attribute value name ums
3 2 15.00 price
1 1 50 hdd GB
2 1 100 hdd TB
You can make a conditional order by in mysql, like this, for example:
user
id name
select *
from user
order by (case when id <5 then id else name end)
However, you've got two tables, you need yo join them, I'm still not sure if you can get what you need this way.
Also, you can't order with DESC on one branch and ASC on another.
Finlay I have get my own answer:
this is the code:
$nr_ordine=0;
$virgula="";
$ordine="valoare";
$ordine2="FIELD(unitate_masura,";
$sql_ums=mysql_query("select * from atribute_masura where id_atribut='".$exe_atribut['id']."' order by ordine asc");
while($exe_ums=mysql_fetch_array($sql_ums))
{
$nr_ordine++;
if($nr_ordine>1)
{
$virgula=",";
};
$ordine2.=$virgula."'".$exe_ums['valoare']."'";
};
$ordine2.=")";
if($ordine2!="FIELD(unitate_masura,)")
{
$ordine=$ordine2;
};
$s_q0=mysql_query("select * from atribute_cautare where id_atribut='".$exe_atribut['id']."' group by valoare order by $ordine asc") or die (mysql_error());
while($s_q=mysql_fetch_array($s_q0))
{
...
};
The names not correspond with my question but this is the idea order by FIELD (ums,'kb','mb','gb','tb')