count repeated row values without breaks - mysql

I want to count repeated values in rows one by one without breaks. If it breaks with NULL value, then count it again from zero.
It is a simple table consists from action_id and event_code.
| id | action_id | event_code |
--------------------------------
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 1 | 300 |
| 4 | 2 | 100 |
| 5 | 2 | 300 |
| 6 | 3 | 100 |
| 7 | 3 | 200 |
| 8 | 3 | 400 |
Then it groups by action_id (with SQL query) to:
| action_id | c100 | c200 | c300 | c400 |
-----------------------------------------
| 1 | 1 | 1 | 1 | 0 |
| 2 | 1 | 0 | 1 | 0 |
| 3 | 1 | 1 | 0 | 1 |
and as a result:
| action_id | c100 | e100_r | c200 | e200_r | c300 | e300_r | c400 | e400_r |
-----------------------------------------------------------------------------
| 1 | 1 | 3 | 1 | 1 | 1 | 2 | 0 | 0 |
| 2 | 1 | 3 | 0 | 0 | 1 | 2 | 0 | 0 |
| 3 | 1 | 3 | 1 | 1 | 0 | 0 | 1 | 1 |
or
| id | action_id | event_code | rep_count |
--------------------------------------------
| 1 | 1 | 100 | 3 |
| 2 | 1 | 200 | 1 |
| 3 | 1 | 300 | 2 |
| 4 | 2 | 100 | 3 |
| 5 | 2 | 300 | 2 |
| 6 | 3 | 100 | 3 |
| 7 | 3 | 200 | 1 |
| 8 | 3 | 400 | 1 |
Is it possible?
EDIT 1:
c100 - couunter of event_code == 100 and e100_r - repeats of event_code == 100
EDIT 2:
Rows breaks by zero (0)

Related

Update records in a select query with different values

I have an INSERT INTO query that works great to create child records when a parent record is added. I basically need to run the same thing but instead of adding new child records, I need to update the column that contains a sum value.
As an example, I have the following data. Shift_Roster_ID is the PK for the first table. RosterID and ShiftID are both foreign keys. For ShiftID=1, I want to update the ShiftCount for each unique RosterID. The ShiftCount is the sum of the Response values for any shift for which the PeriodID in the second table matches the PeriodID of ShiftID=1.
+-----------------+----------+---------+------------+----------+
| Shift_Roster_ID | RosterID | ShiftID | ShiftCount | Response |
+-----------------+----------+---------+------------+----------+
| 1 | 1 | 1 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 2 | 2 | 1 | 0 | 3 |
+-----------------+----------+---------+------------+----------+
| 3 | 3 | 1 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 4 | 1 | 2 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 5 | 2 | 2 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 6 | 3 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 7 | 1 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 8 | 2 | 3 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 9 | 3 | 3 | 0 | 6 |
+-----------------+----------+---------+------------+----------+
+---------+----------+
| ShiftID | PeriodID |
+---------+----------+
| 1 | 1 |
+---------+----------+
| 2 | 1 |
+---------+----------+
| 3 | 2 |
+---------+----------+
The result should be
+-----------------+----------+---------+------------+----------+
| Shift_Roster_ID | RosterID | ShiftID | ShiftCount | Response |
+-----------------+----------+---------+------------+----------+
| 1 | 1 | 1 | **2** | 1 |
+-----------------+----------+---------+------------+----------+
| 2 | 2 | 1 | **11** | 3 |
+-----------------+----------+---------+------------+----------+
| 3 | 3 | 1 | **15** | 8 |
+-----------------+----------+---------+------------+----------+
| 4 | 1 | 2 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 5 | 2 | 2 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 6 | 3 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 7 | 1 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 8 | 2 | 3 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 9 | 3 | 3 | 0 | 6 |
+-----------------+----------+---------+------------+----------+

How to calculate opening and closing stocks for particular date range

How to calculate opening and closing stocks for particular date range
I want to calculate opening and closing stocks for items for a provided date range.
I have tables as follows,
global_items:
+-----+--------+
| id | name |
+-----+--------+
| 1 | item 1 |
+-----+--------+
| 2 | item 2 |
+-----+--------+
| 3 | item 3 |
+-----+--------+
| 4 | item 4 |
+-----+--------+
| ... | ... |
+-----+--------+
my_items:
+-----+----------------+-----------+
| id | global_item_id | outlet_id |
+-----+----------------+-----------+
| 1 | 1 | 7 |
+-----+----------------+-----------+
| 2 | 2 | 7 |
+-----+----------------+-----------+
| 3 | 3 | 7 |
+-----+----------------+-----------+
| 4 | 4 | 7 |
+-----+----------------+-----------+
| ... | ... | ... |
+-----+----------------+-----------+
my_item_stocks:
+-----+------------+---------+---------------+-----------+---------------+-------+
| id | my_item_id | size_id | purchase_rate | sale_rate | opening_stock | stock |
+-----+------------+---------+---------------+-----------+---------------+-------+
| 1 | 1 | 10 | 100 | 200 | 0 | 0 |
+-----+------------+---------+---------------+-----------+---------------+-------+
| 2 | 1 | 11 | 100 | 200 | 0 | 5 |
+-----+------------+---------+---------------+-----------+---------------+-------+
| 3 | 2 | 10 | 100 | 200 | 1.05 | 1.05 |
+-----+------------+---------+---------------+-----------+---------------+-------+
| 4 | 3 | 12 | 100 | 200 | 10 | 10 |
+-----+------------+---------+---------------+-----------+---------------+-------+
| ... | ... | ... | 100 | 200 | 0 | 1 |
+-----+------------+---------+---------------+-----------+---------------+-------+
sizes:
+-----+--------+----------+
| id | name | quantity |
+-----+--------+----------+
| 10 | 750 ml | 750 |
+-----+--------+----------+
| 11 | 500 ml | 500 |
+-----+--------+----------+
| 12 | 350 ml | 350 |
+-----+--------+----------+
| ... | ... | ... |
+-----+--------+----------+
Then I have sales and purchases tables as follows, adding purchase updates the stock in my_item_stocks and adding sale reduces stock.
purchases:
+-----+------------+-----------+
| id | date | outlet_id |
+-----+------------+-----------+
| 1 | 2018-07-01 | 7 |
+-----+------------+-----------+
| 2 | 2018-07-10 | 7 |
+-----+------------+-----------+
| 3 | 2018-07-19 | 7 |
+-----+------------+-----------+
| ... | ... | ... |
+-----+------------+-----------+
purchase_items:
+-----+-------------+------------+---------+----------+
| id | purchase_id | my_item_id | size_id | quantity |
+-----+-------------+------------+---------+----------+
| 1 | 1 | 1 | 10 | 2 |
+-----+-------------+------------+---------+----------+
| 2 | 1 | 2 | 11 | 5 |
+-----+-------------+------------+---------+----------+
| 3 | 2 | 2 | 10 | 17 |
+-----+-------------+------------+---------+----------+
| 4 | 3 | 2 | 12 | 15 |
+-----+-------------+------------+---------+----------+
| 5 | 3 | 2 | 12 | 10 |
+-----+-------------+------------+---------+----------+
| ... | ... | ... | ... | ... |
+-----+-------------+------------+---------+----------+
sales:
+-----+------------+-----------+
| id | date | outlet_id |
+-----+------------+-----------+
| 1 | 2018-07-01 | 7 |
+-----+------------+-----------+
| 2 | 2018-07-10 | 7 |
+-----+------------+-----------+
| 3 | 2018-07-19 | 7 |
+-----+------------+-----------+
| ... | ... | ... |
+-----+------------+-----------+
sale_items:
+-----+-------------+------------+---------+------+
| id | sale_id | my_item_id | size_id | quantity |
+-----+---------+------------+---------+----------+
| 1 | 1 | 1 | 10 | 1 |
+-----+---------+------------+---------+----------+
| 2 | 1 | 2 | 11 | 2 |
+-----+---------+------------+---------+----------+
| 3 | 2 | 2 | 10 | 10 |
+-----+---------+------------+---------+----------+
| 4 | 3 | 2 | 12 | 5 |
+-----+---------+------------+---------+----------+
| 5 | 3 | 2 | 12 | 2 |
+-----+---------+------------+---------+----------+
| ... | ... | ... | ... | ... |
+-----+---------+------------+---------+----------+
Now for selected date range e.g. from 2018-07-01 to 2018-07-19 I want the output like below,
+-----------+--------------------------+--------------------------+--------------------------+--------------------------+
| Item Name | Opening Stock | Purchase | Sale | Closing Stock |
+ +--------------------------+--------------------------+--------------------------+--------------------------+
| | 750 ml | 500 ml | 350 ml | 750 ml | 500 ml | 350 ml | 750 ml | 500 ml | 350 ml | 750 ml | 500 ml | 350 ml |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| Item 1 | | | | 2 | 5 | | 1 | 2 | | 3 | 7 | |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| Item 2 | 1.05 | | | 17 | | | 10 | | | 8.05 | | |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
+-----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
I am not sql pro, how can I achieve this? I am confused because of lot of related tables, just want right direction.
I am doing this is laravel so please suggest even if there is any way to achieve this using eloquent.
Models: GlobalItem, MyItem, MyItemStock, Size, Purchase, PurchaseItem, Sale, SaleItem
Many thanks!

self join with sum field

I have data like this
table t_prod
+---------+----------+-------------+-----------+----------+
|t_prod_id|t_prod_lot|t_prod_sublot|t_prod_card|t_prod_qty|
+---------+----------+-------------+-----------+----------+
| 4 | R001 | 1 | 1 | 6000 |
| 5 | R001 | 1 | 2 | 6000 |
| 6 | R001 | 1 | 3 | 6000 |
| 10 | R001 | 1 | 4 | 6000 |
| 11 | R001 | 1 | 5 | 6000 |
| 12 | R001 | 1 | 6 | 6000 |
| 13 | R001 | 2 | 1 | 6000 |
| 34 | R001 | 2 | 2 | 6000 |
| 36 | R001 | 2 | 3 | 2000 |
+---------+----------+-------------+-----------+----------+
and i want result like this when i select t_prod_lot = R001. count t_prod_sublot when same value and sum t_prod_qty when t_prod_sublot same value
+---------+----------+-------------+-----------+----------+--------------------+---------------+
|t_prod_id|t_prod_lot|t_prod_sublot|t_prod_card|t_prod_qty|count(t_prod_sublot)|sum(t_prod_qty)|
+---------+----------+-------------+-----------+----------+--------------------+---------------+
| 4 | R001 | 1 | 1 | 6000 | 6 | 36000 |
| 5 | R001 | 1 | 2 | 6000 | 6 | 36000 |
| 6 | R001 | 1 | 3 | 6000 | 6 | 36000 |
| 10 | R001 | 1 | 4 | 6000 | 6 | 36000 |
| 11 | R001 | 1 | 5 | 6000 | 6 | 36000 |
| 12 | R001 | 1 | 6 | 6000 | 6 | 36000 |
| 13 | R001 | 2 | 1 | 6000 | 3 | 14000 |
| 34 | R001 | 2 | 2 | 6000 | 3 | 14000 |
| 36 | R001 | 2 | 3 | 2000 | 3 | 14000 |
+---------+----------+-------------+-----------+----------+--------------------+---------------+
what is the query to produce this result ?
Sql Fiddle
Here's one option using a join with a subquery to count and sum the values:
select *
from t_prod t join (
select t_prod_lot, t_prod_sublot,
count(t_prod_card) t_prod_card_cnt,
sum(t_prod_qty) t_prod_qty_sum
from t_prod
group by t_prod_lot, t_prod_sublot
) t2 on t.t_prod_lot = t2.t_prod_lot and t.t_prod_sublot = t2.t_prod_sublot
Updated SQL Fiddle

How to update multiple rows using single where clause

I have a table test and the structure is as shown below
mysql> select * from test;
+----+------------+------------+---------+-----+------+------+
| id | is_deleted | sort_order | version | cid | pid | qid |
+----+------------+------------+---------+-----+------+------+
| 14 | | 6 | 0 | 1 | 2 | 7 |
| 18 | | 1 | 2 | 1 | 4 | 12 |
| 26 | | 9 | 0 | 1 | 1 | 1 |
| 40 | | 1 | 0 | 1 | 5 | 18 |
| 49 | | 2 | 0 | 1 | 5 | 35 |
| 50 | | 3 | 0 | 1 | 5 | 39 |
| 51 | | 4 | 0 | 1 | 5 | 40 |
| 61 | | 10 | 0 | 1 | 1 | 2 |
| 62 | | 11 | 0 | 1 | 1 | 3 |
| 63 | | 12 | 0 | 1 | 1 | 4 |
| 64 | | 13 | 0 | 1 | 1 | 42 |
| 65 | | 14 | 0 | 1 | 1 | 43 |
| 66 | | 2 | 0 | 1 | 4 | 26 |
| 67 | | 3 | 0 | 1 | 4 | 38 |
| 71 | | 7 | 0 | 1 | 2 | 2 |
| 72 | | 8 | 0 | 1 | 2 | 8 |
| 73 | | 9 | 0 | 1 | 2 | 50 |
| 74 | | 10 | 0 | 1 | 2 | 51 |
| 76 | | 3 | 0 | 1 | 3 | 9 |
| 78 | | 4 | 0 | 1 | 3 | 53 |
| 79 | | 1 | 0 | 1 | 6 | 54 |
| 80 | | 1 | 0 | 1 | 11 | 59 |
| 81 | | 1 | 0 | 1 | 12 | 70 |
+----+------------+------------+---------+-----+------+------+
I want to set version to 1 of all the rows whose cid =1,pid not equal to 6,11 and qid not equal to 28,59,54
Can anybody please tell me how to do?
UPDATE test
SET `version` = 1
WHERE cid =1
AND pid NOT in(6,11)
AND qid NOT IN (28,59,54);

How do I UPDATE a value only WHERE COUNT(subquery using GROUP BY)=1?

I'm attempting to set a row value to 1 when it is the only row in a group, with a single query.
Current Table (CATEGORY_BRAND):
|categoryId | brandId | featured |
|-----------+---------+----------|
| 1 | 100 | -1 |
| 1 | 101 | -1 |
| 1 | 102 | -1 |
| 2 | 100 | -1 |
| 3 | 110 | -1 |
| 3 | 111 | -1 |
| 4 | 102 | -1 |
| 5 | 101 | -1 |
| 6 | 100 | -1 |
| 6 | 110 | -1 |
| ... | ... | ... |
Hoped for Result (CATEGORY_BRAND):
|categoryId | brandId | featured |
|-----------+---------+----------|
| 1 | 100 | -1 |
| 1 | 101 | -1 |
| 1 | 102 | -1 |
| 2 | 100 | 1 |
| 3 | 110 | -1 |
| 3 | 111 | -1 |
| 4 | 102 | 1 |
| 5 | 101 | 1 |
| 6 | 100 | -1 |
| 6 | 110 | -1 |
| ... | ... | ... |
(My sincerest apologies if this is a duplicate, I couldn't find anyone else doing an UPDATE like this.)
This may not be the most performant, but should work (although you should test it first).
UPDATE category_brand JOIN (
SELECT categoryId
FROM category_brand
GROUP BY categoryId
HAVING COUNT(categoryId) = 1)
AS single_cbs USING(categoryId) SET category_brand.featured = 1;