Suppose I have the following MySQL table:
I would like to know the total volume for Fuji Apples for the 3 days before the latest sale date (like a moving total). So for this example, I am after the total volume for my selection for the 3 days prior to the 04/01/14, which is 9.
I have made a number of attempts without the intended results:
SELECT sum(volume) FROM (SELECT `volume` FROM `fruit_sale_db` WHERE `fruit` = 'apple' AND `type` = 'fuji') AS subquery ORDER BY `date` DESC LIMIT 1,3
I thought ORDER BY date DESC LIMIT 1,3 would work by restricting dates to 3 starting from the second last entry but it doesn't work.
SELECT sum(volume) FROM `fruit_sale_db` where 'date' >= (latest_sale_date - 3) and 'date' <= latest_sale_date and `fruit` = 'apple' AND `type` = 'fuji'
and latest_sale_date would be something like
SELECT `date` FROM `fruit_sale_db` WHERE `fruit` = 'apple' AND `type` = 'fuji' ORDER BY `date` DESC LIMIT 1
Consider the following...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,Fruit VARCHAR(12) NOT NULL
,Type VARCHAR(12) NOT NULL
,Date DATE NOT NULL
,Volume INT NOT NULL
);
INSERT INTO my_table (fruit,type,date,volume) VALUES
('Apple','Fuji' ,'2014-01-01',1),
('Apple','Other','2014-01-01',6),
('Apple','Fuji' ,'2014-01-01',2),
('Apple','Other','2014-01-02',1),
('Apple','Other','2014-01-02',4),
('Apple','Fuji' ,'2014-01-03',4),
('Apple','Other','2014-01-03',2),
('Apple','Fuji' ,'2014-01-04',8),
('Apple','Fuji' ,'2014-01-05',16),
('Pear' ,'Other','2014-01-06',1),
('Apple','Other','2014-01-06',4),
('Apple','Fuji' ,'2014-01-07',32),
('Apple','Other','2014-01-07',2),
('Apple','Fuji' ,'2014-01-08',64);
SELECT * FROM my_table;
+----+-------+-------+------------+--------+
| id | Fruit | Type | Date | Volume |
+----+-------+-------+------------+--------+
| 1 | Apple | Fuji | 2014-01-01 | 1 |
| 2 | Apple | Other | 2014-01-01 | 6 |
| 3 | Apple | Fuji | 2014-01-01 | 2 |
| 4 | Apple | Other | 2014-01-02 | 1 |
| 5 | Apple | Other | 2014-01-02 | 4 |
| 6 | Apple | Fuji | 2014-01-03 | 4 |
| 7 | Apple | Other | 2014-01-03 | 2 |
| 8 | Apple | Fuji | 2014-01-04 | 8 |
| 9 | Apple | Fuji | 2014-01-05 | 16 |
| 10 | Pear | Other | 2014-01-06 | 1 |
| 11 | Apple | Other | 2014-01-06 | 4 |
| 12 | Apple | Fuji | 2014-01-07 | 32 |
| 13 | Apple | Other | 2014-01-07 | 2 |
| 14 | Apple | Fuji | 2014-01-08 | 64 |
+----+-------+-------+------------+--------+
SELECT a.*
, SUM(b.volume) rolling
, GROUP_CONCAT(b.volume ORDER BY b.id DESC SEPARATOR '+' ) math
FROM my_table a
LEFT
JOIN my_table b
ON b.fruit = a.fruit
AND b.type = a.type
AND b.date BETWEEN a.date - INTERVAL 3 DAY AND a.date - INTERVAL 1 DAY
GROUP
BY a.id
ORDER
BY fruit, type, id DESC;
+----+-------+-------+------------+--------+---------+-------+
| id | Fruit | Type | Date | Volume | rolling | math |
+----+-------+-------+------------+--------+---------+-------+
| 14 | Apple | Fuji | 2014-01-08 | 64 | 48 | 32+16 |
| 12 | Apple | Fuji | 2014-01-07 | 32 | 24 | 16+8 |
| 9 | Apple | Fuji | 2014-01-05 | 16 | 12 | 8+4 |
| 8 | Apple | Fuji | 2014-01-04 | 8 | 7 | 4+2+1 |
| 6 | Apple | Fuji | 2014-01-03 | 4 | 3 | 2+1 |
| 3 | Apple | Fuji | 2014-01-01 | 2 | NULL | NULL |
| 1 | Apple | Fuji | 2014-01-01 | 1 | NULL | NULL |
| 13 | Apple | Other | 2014-01-07 | 2 | 4 | 4 |
| 11 | Apple | Other | 2014-01-06 | 4 | 2 | 2 |
| 7 | Apple | Other | 2014-01-03 | 2 | 11 | 4+1+6 |
| 5 | Apple | Other | 2014-01-02 | 4 | 6 | 6 |
| 4 | Apple | Other | 2014-01-02 | 1 | 6 | 6 |
| 2 | Apple | Other | 2014-01-01 | 6 | NULL | NULL |
| 10 | Pear | Other | 2014-01-06 | 1 | NULL | NULL |
+----+-------+-------+------------+--------+---------+-------+
http://sqlfiddle.com/#!2/5243e/1
Related
I am generating sequential reference numbers like complaint/1, complaint/2 when an insertion is made. I get what the previously generated value is (complaint/2) and then increment.
But when two users submit at the same time, I sometimes get same reference nos for both complaints.
How do I prevent this?
SELECT RIGHT(Date_format(from_financial_year_,'%Y'),2),
RIGHT(Date_format(to_financial_year_,'%Y'),2)
INTO from_financial_year_,
to_financial_year_;SELECT rec.receipt_ref_no
INTO last_receipt_ref_num_
FROM svk_apt_receipts rec
WHERE Replace(Substring_index(rec.receipt_ref_no, '/', 2),'REC/','') = Concat(from_financial_year_,to_financial_year_)
AND rec.customer_id = customer_id_
AND rec.association_id = association_id_
ORDER BY rec.receipt_id DESC limit 1;IF(last_receipt_ref_num_ IS NULL) then
SELECT 1
INTO max_ref_id_;
else
SELECT (replace(last_receipt_ref_num_, concat('REC/',from_financial_year_,to_financial_year_,'/'),'')+1)
INTO max_ref_id_;ENDIF;SELECT Concat('REC/',from_financial_year_,to_financial_year_,'/',max_ref_id_)
INTO receipt_ref_no_;INSERT INTO svk_apt_receipts
(
receipt_ref_no, paid, payable, is_paid, master_receipt_to_id, receipt_from_id, receipt_to_id, receipt_date,
receipt_mode, transaction_ref_no, customer_id, association_id, is_active, created_by, created_on, receipt_status_id, remarks
)
VALUES
( receipt_ref_no_, _total_amount, 0,1,3, receipt_from_id_, receipt_to_id_, Cast(Now()AS DATE), 3, _transaction_ref_no,
customer_id_, association_id_, 1, _created_by, Now(), 2, 'Paid through Payment Gateway'
);
As mentioned in comments, just store an autoincrementing id. All the other stuff can be handled by trivial queries and/or your presentation layer.
By way of example...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,user INT NOT NULL
);
INSERT INTO my_table (user) VALUES
(1),(1),(3),(3),(5),(2),(1),(8),(4),(5),(7),(5),(5),(4),(1),(2),(3),(6),(4),(6),(1),(5),(1),(8);
SELECT * FROM my_table;
+----+------+
| id | user |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
| 4 | 3 |
| 5 | 5 |
| 6 | 2 |
| 7 | 1 |
| 8 | 8 |
| 9 | 4 |
| 10 | 5 |
| 11 | 7 |
| 12 | 5 |
| 13 | 5 |
| 14 | 4 |
| 15 | 1 |
| 16 | 2 |
| 17 | 3 |
| 18 | 6 |
| 19 | 4 |
| 20 | 6 |
| 21 | 1 |
| 22 | 5 |
| 23 | 1 |
| 24 | 8 |
+----+------+
24 rows in set (0.01 sec)
SELECT x.*
, COUNT(*) complaint
FROM my_table x
JOIN my_table y
ON y.user = x.user
AND y.id <= x.id
GROUP
BY x.id
ORDER
BY user
, id;
+----+------+-----------+
| id | user | complaint |
+----+------+-----------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 7 | 1 | 3 |
| 15 | 1 | 4 |
| 21 | 1 | 5 |
| 23 | 1 | 6 |
| 6 | 2 | 1 |
| 16 | 2 | 2 |
| 3 | 3 | 1 |
| 4 | 3 | 2 |
| 17 | 3 | 3 |
| 9 | 4 | 1 |
| 14 | 4 | 2 |
| 19 | 4 | 3 |
| 5 | 5 | 1 |
| 10 | 5 | 2 |
| 12 | 5 | 3 |
| 13 | 5 | 4 |
| 22 | 5 | 5 |
| 18 | 6 | 1 |
| 20 | 6 | 2 |
| 11 | 7 | 1 |
| 8 | 8 | 1 |
| 24 | 8 | 2 |
+----+------+-----------+
24 rows in set (0.00 sec)
i need help to calculate a value inside a hierarchy array. I have a table like this:
+--------+------------+-------+-----------+
| kia_id | kia_name | value | parent_id |
+--------+------------+-------+-----------+
| 1 | ac service | | 0 |
| 2 | hil | | 0 |
| 3 | dispatch | | 1 |
| 4 | tat main | 13.3 | 3 |
| 5 | tat air | 10.1 | 3 |
| 6 | sla comp | 11.7 | 2 |
| 7 | sla serv | | 2 |
| 8 | slb | 9.9 | 7 |
+--------+------------+-------+-----------+
i want to display to html that table like this :
+--------+----------------+-------+-----------+------------------------+
| kia_id | kia_name | value | parent_id | total_value_from_child |
+--------+----------------+-------+-----------+------------------------+
| 1 | ac service | | 0 | 23.4 |
| 3 | dispatch | | 1 | 23.4 |
| 4 | tat main | 13.3 | 3 | |
| 5 | tat air | 10.1 | 3 | |
| 2 | hil | | 0 | 21.6 |
| 6 | sla comp | 11.7 | 2 | |
| 7 | sla serv | | 2 | 9.9 |
| 8 | slb | 9.9 | 7 | |
+--------+----------------+-------+-----------+------------------------+
how to count all child value to set the total of this parent, please help me..
I think you need to combine a recursive CTE with aggregation. The idea is to start at the "bottom" (leafs) and work your way up. Then aggregate to bring in the original data.
with cte as (
select kia_id, value, kia_id as parent_id, 0 as lev
from t
where not exists (select 1 from t t2 where t2.parent_id = t.kia_id)
union all
select cte.kia_id, cte.kia_value, t.parent_id, cte.lev + 1
from cte join
t
on cte.parent_id = t.kia_id
)
select t.*, c.parent_value
from (select cte.parent_id, sum(kia_value) as parent_value
from cte
group by cte.parent_id
) c join
t
on t.kia_id = c.parent_id;
I have a MYSQL table that looks like:
+----+--------------+------------+----------------+---------------------+
| id | id_solicitud | id_estatus | id_responsable | fecha_hora |
+----+--------------+------------+----------------+---------------------+
| 1 | 1 | 1 | 3 | 2017-11-20 11:12:05 |
| 3 | 1 | 2 | 3 | 2017-11-20 13:30:50 |
| 4 | 2 | 1 | 5 | 2017-11-20 13:42:35 |
| 5 | 2 | 2 | 5 | 2017-11-20 13:52:25 |
| 6 | 1 | 4 | 2 | 2017-11-21 12:20:17 |
| 8 | 2 | 3 | 2 | 2017-11-21 13:39:57 |
| 9 | 2 | 2 | 5 | 2017-11-21 13:40:55 |
| 10 | 2 | 4 | 2 | 2017-11-21 13:45:24 |
+----+--------------+------------+----------------+---------------------+
Then, I proceed to filter by the id_solicitud field with the following Mysql QUERY:
SELECT id_estatus, id_responsable, fecha_hora FROM estatus_historico WHERE id_solicitud =2 ORDER BY fecha_hora
The result:
+------------+----------------+---------------------+
| id_estatus | id_responsable | fecha_hora |
+------------+----------------+---------------------+
| 1 | 5 | 2017-11-20 13:42:35 |
| 2 | 5 | 2017-11-20 13:52:25 |
| 3 | 2 | 2017-11-21 13:39:57 |
| 2 | 5 | 2017-11-21 13:40:55 |
| 4 | 2 | 2017-11-21 13:45:24 |
+------------+----------------+---------------------+
I want to apply the distinct operator over id_estatus column but selecting the older row when duplicate rows are found, i.e. my desired result is:
+------------+----------------+---------------------+
| id_estatus | id_responsable | fecha_hora |
+------------+----------------+---------------------+
| 1 | 5 | 2017-11-20 13:42:35 |
| 3 | 2 | 2017-11-21 13:39:57 |
| 2 | 5 | 2017-11-21 13:40:55 |
| 4 | 2 | 2017-11-21 13:45:24 |
+------------+----------------+---------------------+
I tried:
SELECT id_estatus, id_responsable, fecha_hora FROM estatus_historico WHERE id_solicitud =2 GROUP BY id_estatus ORDER BY fecha_hora
But the result is wrong:
+------------+----------------+---------------------+
| id_estatus | id_responsable | fecha_hora |
+------------+----------------+---------------------+
| 1 | 5 | 2017-11-20 13:42:35 |
| 2 | 5 | 2017-11-20 13:52:25 |
| 3 | 2 | 2017-11-21 13:39:57 |
| 4 | 2 | 2017-11-21 13:45:24 |
+------------+----------------+---------------------+
Any help would be much appreciated
UPDATE: Files to create table and insert data => estatus_historico.sql
try this one
SELECT id_estatus, id_responsable, MAX(fecha_hora) FROM estatus_historico WHERE id_solicitud =2 GROUP BY id_estatus ORDER BY fecha_hora
Thanks to Rahul Shrivastava, I finally found the correct answer:
SELECT * FROM (
SELECT id_estatus, id_responsable, MAX( fecha_hora ) AS fecha
FROM estatus_historico
WHERE id_solicitud =2
GROUP BY id_estatus
ORDER BY fecha_hora
) AS MY_TABLE ORDER BY fecha
I need help to resolve this.
I have 4 tables :
Transactions
| id | cid | gt | rt |
| 1 | 6 | 2 | 5 |
| 2 | 6 | 9 | 7.5 |
| 3 | 6 | 3 | 9.7 |
| 4 | 3 | 3 | 7.0 |
| 5 | 3 | 7 | 6.8 |
| 6 | 9 | 4 | 2.5 |
| 7 | 9 | 2 | 5.4 |
Clients
| id | firstname | lastname | date |
| 1 | jean | moulin | 1987 |
| 2 | salah | fera | 1968
| 3 | marouan | youra | 2001 |
| 4 | amin | esa | 1963 |
| 5 | kamal | tara | 1789 |
| 6 | moad | mara | 2005 |
| 9 | safaa | dara | 2004 |
Produit A
| id | cid |
| 1 | 6 |
| 2 | 6 |
| 3 | 3 |
| 4 | 3 |
| 5 | 3 |
| 6 | 4 |
| 7 | 1 |
Produit B
| id | cid |
| 1 | 6 |
| 2 | 3 |
| 3 | 9 |
| 4 | 3 |
| 5 | 3 |
| 6 | 4 |
| 7 | 6 |
The result that i need is :
cid | name | date | pa | pb | gt | rt |
3 | | | | | | |
6 | | | | | | |
9 | | | | | | |
I need to select from transaction all distinct client id (pid) and select the firstname and last name (name = firstname lastname) and date from clients table and sum all values (gt) and (rt) and search in table produitA the number of products for this client by his id and the same thing for the table produitB.
What i do for this but it don't work is (suggested by Gimeniux):
SELECT
clients.id,
CONCAT(firstname, ' ', lastname) as name,
date,
count(distinct produitA.id) as pa,
count(distinct produitB.id) as pb,
sum(gt) AS gt,
sum(rt) AS rt
FROM clients
LEFT JOIN transactions ON clients.id = transactions.pid
LEFT JOIN produitA ON clients.id = produitA.cid
LEFT JOIN produitB ON clients.id = produitB.cid
where pid is not null
group by clients.id
The probleme here is that gt and rt values are true for only the first client. For the second client and third and ... there is different values that are not true.
Although is hard for me to see the logic between your tables, you can use this query to get the result you desire. But i think it won't work if there are two same 'gt' or two same 'rt' values for one client.
SELECT
clients.id,
CONCAT(firstname, ' ', lastname) as name,
date,
count(distinct produitA.id) as pa,
count(distinct produitB.id) as pb,
sum(distinct gt) AS gt,
sum(distinct rt) AS rt
FROM clients
LEFT JOIN transactions ON clients.id = transactions.pid
LEFT JOIN produitA ON clients.id = produitA.cid
LEFT JOIN produitB ON clients.id = produitB.cid
where pid is not null
group by clients.id
Row for pid=9 doesn't show because in the data you gave there is no client with id=9
I want to concatenate and count data of the same column, so I can concatenate but I can not count the repeated data.
Here's my table of data:
| ID | bills | class |
|-----|-------|-------|
| 1 | 0.5 | 2 |
| 2 | 1 | 1 |
| 3 | 0.5 | 2 |
| 5 | 1 | 3 |
| 6 | 0 | 2 |
| 7 | 0.5 | 1 |
| 8 | 1 | 2 |
| 9 | 1 | 3 |
| 10 | 0.5 | 1 |
| 11 | 0 | 2 |
| 12 | 1 | 1 |
| 13 | 0 | 3 |
| 14 | 1 | 2 |
| 15 | 0 | 1 |
| 16 | 0 | 1 |
| 17 | 0.5 | 3 |
| 18 | 0 | 3 |
| 13 | 0.5 | 3 |
Here's my sql query I'm using to concatenate data:
SELECT class AS lesson,
GROUP_CONCAT( bills ORDER BY bills ) AS bills
FROM tb_presence
GROUP BY class;
Here's my result below:
| class | bills |
|-------|------------------|
| 1 | 1,0.5,0.5,1,0,0 |
| 2 | 0.5,0,1,0,1 |
| 3 | 1,1,0,0.5,0,0.5 |
Now I would like to count the data that are equal, but continue with the same concatenation.
I want to "count" the data with the same values and display concatenated (column observation and only to help understanding)
| class | bills | observation |
|-------|-------|-----------------------------|
| 1 | 2,2,2 | (2=0+0) (2=0.5+0.5) (2=1+1) |
| 2 | 2,1,2 | (2=0+0) (1=0.5) (2=1+1) |
| 3 | 2,2,2 | (2=0+0) (2=0.5+0.5) (2=1+1) |
Is this really possible?
Here is a solution (thanks to #wchiquito for the sqlfiddle) See http://sqlfiddle.com/#!2/2d2c8/1
As you can see it cannot dynamically determine the bills' values and count them. But there is a count per bill value that you want.
SELECT class AS lesson,
GROUP_CONCAT( bills ORDER BY bills ) AS bills
,SUM(IF(bills=0,1,0)) AS Count0
,SUM(IF(bills=0.5,1,0)) AS Count05
,SUM(IF(bills=1,1,0)) AS Count1
,COUNT(*) AS totalRecords
,COUNT(*)
- SUM(IF(bills=0,1,0))
- SUM(IF(bills=0.5,1,0))
- SUM(IF(bills=1,1,0))
AS Missing
FROM tb_presence GROUP BY class;
I added an extra record to show how the 'missing' column could show if you were not taking all values into consideration.
Results
| LESSON | BILLS | COUNT0 | COUNT05 | COUNT1 | TOTALRECORDS | MISSING |
|--------|-----------------------------------------|--------|---------|--------|--------------|---------|
| 1 | 0.00,0.00,0.50,0.50,1.00,1.00,1.00,4.00 | 2 | 2 | 3 | 8 | 1 |
| 2 | 0.00,0.00,0.50,0.50,1.00,1.00 | 2 | 2 | 2 | 6 | 0 |
| 3 | 0.00,0.00,0.50,0.50,1.00,1.00 | 2 | 2 | 2 | 6 | 0 |