I have below mentioned two tables:
Table 1
ID Key
TTT-1 atre-0-1
TTT-2 atrt-4-2
TTT-3 attr-1-3
TTT-4 aert-2-5
Table2
Key Red1 Red2
atre-0-1 10 25
atre-0-1 15 07
atre-0-1 16 19
atrt-4-2 11 21
atrt-4-2 07 22
attr-1-3 -4 3
attr-1-3 33 11
attr-1-3 50 45
aert-2-5 -5 2
aert-2-5 -4 1
By utilizing the above tow tables, I want to fetch the minimum value of Red1 and Red2 group by ID with the below mentioned condition.
For any ID if any Red1 and Red2 value is between -5 to 5 than consider the other values which are maximum of five, If there are only one entry available for a ID against which value is between range -5 to 5 than only consider -5 to 5 value for minimum criteria.
Required Output:
ID Number
TTT-1 07
TTT-2 07
TTT-3 11
TTT-4 -5
I have written below mentioned query, but it didn't work properly.
select t1.ID,
case when min(t2.Red1)<min(t2.Red2) then min(t2.Red1) else min(t2.Red2) End as `Number`
from Table1 t1
left join Table2 t2 on t1.key=t2.key
group by t1.ID;
The following query should solve this problem:
SELECT t1.ID,
CASE WHEN min(t2.Red1)<min(t2.Red2) THEN t2.min_red1 ELSE t2.min_red2 END AS
`Number`
FROM Table1 t1
LEFT JOIN
(
SELECT
key,
Red1
Red2
min(Red1) AS min_red1,
min(Red2) AS min_red2
FROM Table2 ) AS t2
ON t1.key=t2.key
GROUP BY t1.ID;
You can use the below SQL, here is the example as per your expectation.
Query:
SELECT
a.ID,
CASE
WHEN
LEAST(MIN(b.red1), MIN(b.red2)) BETWEEN - 5 AND 5
THEN
IFNULL(LEAST(MIN(CASE
WHEN red1 NOT BETWEEN - 5 AND 5 THEN red1
END),
MIN(CASE
WHEN red2 NOT BETWEEN - 5 AND 5 THEN red2
END)),
LEAST(MIN(b.red1), MIN(b.red2)))
ELSE LEAST(MIN(b.red1), MIN(b.red2))
END AS `Number`
FROM
table1 a
JOIN
table2 b ON a.key = b.key
GROUP BY a.ID;
Example:
mysql> create table table1(ID varchar(20),`key` varchar(20));
Query OK, 0 rows affected (0.23 sec)
mysql> insert into table1 values
-> ('TTT-1','atre-0-1'),
-> ('TTT-2','atrt-4-2'),
-> ('TTT-3','attr-1-3'),
-> ('TTT-4','aert-2-5');
Query OK, 4 rows affected (0.27 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql>
mysql> create table table2(`key` varchar(20),red1 int(5),red2 int(5));
Query OK, 0 rows affected (0.30 sec)
mysql> insert into table2 values
-> ('atre-0-1',10,25),
-> ('atre-0-1',15,07),
-> ('atre-0-1',16,19),
-> ('atrt-4-2',11,21),
-> ('atrt-4-2',07,22),
-> ('attr-1-3',-4,3),
-> ('attr-1-3',33,11),
-> ('attr-1-3',50,45),
-> ('aert-2-5',-5,2),
-> ('aert-2-5',-4,1);
Query OK, 10 rows affected (0.29 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql>
mysql> select * from table1;
+-------+----------+
| ID | key |
+-------+----------+
| TTT-1 | atre-0-1 |
| TTT-2 | atrt-4-2 |
| TTT-3 | attr-1-3 |
| TTT-4 | aert-2-5 |
+-------+----------+
4 rows in set (0.20 sec)
mysql> select * from table2;
+----------+------+------+
| key | red1 | red2 |
+----------+------+------+
| atre-0-1 | 10 | 25 |
| atre-0-1 | 15 | 7 |
| atre-0-1 | 16 | 19 |
| atrt-4-2 | 11 | 21 |
| atrt-4-2 | 7 | 22 |
| attr-1-3 | -4 | 3 |
| attr-1-3 | 33 | 11 |
| attr-1-3 | 50 | 45 |
| aert-2-5 | -5 | 2 |
| aert-2-5 | -4 | 1 |
+----------+------+------+
10 rows in set (0.21 sec)
mysql>
mysql> SELECT
-> a.ID,
-> CASE
-> WHEN
-> LEAST(MIN(b.red1), MIN(b.red2)) BETWEEN - 5 AND 5
-> THEN
-> IFNULL(LEAST(MIN(CASE
-> WHEN red1 NOT BETWEEN - 5 AND 5 THEN red1
-> END),
-> MIN(CASE
-> WHEN red2 NOT BETWEEN - 5 AND 5 THEN red2
-> END)),
-> LEAST(MIN(b.red1), MIN(b.red2)))
-> ELSE LEAST(MIN(b.red1), MIN(b.red2))
-> END AS `Number`
-> FROM
-> table1 a
-> JOIN
-> table2 b ON a.key = b.key
-> GROUP BY a.ID;
+-------+--------+
| ID | Number |
+-------+--------+
| TTT-1 | 7 |
| TTT-2 | 7 |
| TTT-3 | 11 |
| TTT-4 | -5 |
+-------+--------+
4 rows in set (0.28 sec)
Related
this is my code
UPDATE `mytable`
SET `income` = (SELECT sum(`row`) FROM (SELECT * FROM `mytable`)AS mmc WHERE `view_date` = '2018-5-21')
WHERE id = 1 AND view_date = '2018-5-21'
I run this code and it successful, but my data was not update.
You can use the below SQL to update your table properly.
SQL:
update mytable m
join (select id,view_date,sum(row) as row from mytable group by id,view_date) t on (m.id = t.id and m.view_date = t.view_date)
set m.income = t.row
where m.id = 1 and m.view_date = '2018-05-23';
Example are below:
mysql> create table mytable(id int,income int, row int, view_date date);
Query OK, 0 rows affected (0.54 sec)
mysql> insert into mytable values(1,null,230,current_date);
Query OK, 1 row affected (0.12 sec)
mysql> insert into mytable values(1,null,450,current_date);
Query OK, 1 row affected (0.05 sec)
mysql> select * from mytable;
+------+--------+------+------------+
| id | income | row | view_date |
+------+--------+------+------------+
| 1 | NULL | 230 | 2018-05-23 |
| 1 | NULL | 450 | 2018-05-23 |
| 2 | NULL | 800 | 2018-05-23 |
+------+--------+------+------------+
3 rows in set (0.00 sec)
mysql> update mytable m
-> join (select id,view_date,sum(row) as row from mytable group by id,view_date) t on (m.id = t.id and m.view_date = t.view_date)
-> set m.income = t.row
-> where m.id = 1 and m.view_date = '2018-05-23';
Query OK, 2 rows affected (0.13 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from mytable;
+------+--------+------+------------+
| id | income | row | view_date |
+------+--------+------+------------+
| 1 | 680 | 230 | 2018-05-23 |
| 1 | 680 | 450 | 2018-05-23 |
| 2 | NULL | 800 | 2018-05-23 |
+------+--------+------+------------+
3 rows in set (0.00 sec)
I have two tables. First table stk
ITEMID | STOCK
--------------
Test1 | 10
Test2 | 15
Test3 | 12
and second table qty
ITEMID | DOCDATE | QTY
--------------------------
Test1 | 2/28/2017 | 5
Test2 | 2/28/2017 | 8
Test3 | 2/28/2017 | 6
I used this query
select itemid,stock,docdate,qty
from (
select itemid,stock,null docdate,0 qty from stk
union
select itemid,0 stock,docdate,qty from qty
)
group by itemid,stock,docdate,qty
order by 1
Output I get:
ITEMID | STOCK | DOCDATE | QTY
------------------------------
Test1 | 0 |2/28/2017 | 5
Test1 | 10 | | 0
Test2 | 0 |2/28/2017 | 8
Test2 | 15 | | 0
Test3 | 0 |2/28/2017 | 6
Test3 | 12 | | 0
but I want to have this output:
ITEMID | STOCK | DOCDATE | QTY
------------------------------
Test1 | 10 |2/28/2017 | 5
Test2 | 15 |2/28/2017 | 8
Test3 | 12 |2/28/2017 | 6
If you only want to consolidate rows coming from the two different tables then you can use this query:
select itemid, MAX(stock), MAX(docdate), MAX(qty)
from (
select itemid,stock,null docdate,0 qty from stk
union
select itemid,0 stock,docdate,qty from qty
) as t
group by itemid
order by 1
Demo here
If your only goal is to have that output, then you can just do this:
SELECT Q.ItemId, (SELECT S.stock FROM stk S ON S.ItemId = Q.ItemId) AS STOCK, Q.DocDate, Q.Qty FROM qty Q
I am using subqueries to connect the two tables on Id, and then I select the stock from Stk where the ItemId is the same as the ItemId from Qty.
Unions are vertical joins are horizontal. Perhaps something like this is required.
MariaDB [sandbox]> create table stk(ITEMID varchar(10), STOCK int);
Query OK, 0 rows affected (0.20 sec)
MariaDB [sandbox]> insert into stk values
-> ('Test1' , 10),
-> ('Test2' , 15),
-> ('Test3' , 12);
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> drop table if exists qty;
Query OK, 0 rows affected (0.14 sec)
MariaDB [sandbox]> create table qty(ITEMID varchar(10), DOCDATE varchar(10) , QTY int);
Query OK, 0 rows affected (0.20 sec)
MariaDB [sandbox]> insert into qty values
-> ('Test1' , '2/28/2017' , 5),
-> ('Test2' , '2/28/2017' , 8),
-> ('Test3' , '2/28/2017' , 6),
-> ('Test1' , '3/28/2017' , 7),
-> ('Test2' , '3/28/2017' , 7),
-> ('Test3' , '3/28/2017' , 7);
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> select s.itemid,s.stock,
-> q.docdate,sum(q.qty) qty
-> from stk s
-> join qty q on q.itemid = s.itemid
-> group by s.itemid,s.stock,q.docdate
-> order by q.docdate, s.itemid,s.stock
->
-> ;
+--------+-------+-----------+------+
| itemid | stock | docdate | qty |
+--------+-------+-----------+------+
| Test1 | 10 | 2/28/2017 | 5 |
| Test2 | 15 | 2/28/2017 | 8 |
| Test3 | 12 | 2/28/2017 | 6 |
| Test1 | 10 | 3/28/2017 | 7 |
| Test2 | 15 | 3/28/2017 | 7 |
| Test3 | 12 | 3/28/2017 | 7 |
+--------+-------+-----------+------+
6 rows in set (0.00 sec)
Use JOIN to get result:
SELECT ITEMID ,STOCK,DOCDATE,QTY
FROM table1
JOIN table2 ON table1.ITEMID = table2.ITEMID
I have a table that look like this:
S_ID | DATE
1 2016-01-01
1 2016-01-02
1 2016-01-02
1 2016-01-05
1 2016-01-05
2 2017-01-02
2 2017-01-04
2 2017-01-04
2 2017-01-04
2 2017-01-04
2 2017-01-05
I am trying, in a single query to have the result below (adding cumulatively the records in time)
DATE | S_ID 1 | S_ID 2
2016-01-01 | 1 | 0
2016-01-02 | 3 | 1
2016-01-03 | 3 | 1
2016-01-04 | 3 | 5
2016-01-05 | 5 | 6
Any suggestions?
Try this using group on date and conditional sum along with user variables to get cumulative sum.
Select date,
#s1 := #s1 + s_id_1 s_id_1,
#s2 := #s2 + s_id_2 s_id_2
From (select
date,
sum(s_id = 1) s_id_1,
sum(s_id = 2) s_id_2
from your_table
group by date
Order by date) t cross join (select #s1 := 0, #s2 :=0 ) t2;
It uses the fact that the true is 1 and false is 0 in mysql
You should better use
select
t.s_ID,
t.`date`,
(SELECT SUM(1) FROM table x WHERE x.`date` <= t.`date` AND x.S_ID = t.S_ID) AS cumulative_sum
from table t
group by s_ID,`date`;
This will not provide your desired result, but a form of the result which works independent of the number of users, while the information stays the same:
s_ID | DATE | cumulative_sum
1 2016-01-01 1
1 2016-01-02 3
1 2016-01-05 5
2 2016-01-02 1
2 2016-01-04 5
2 2016-01-05 6
(If there's no entry for an id/date pair, the count didn't change that day)
You can arrived this with a PREPARED Statement. The first Query will generate a query with all s_id in your table. You only must change YOYOURTABLE to your table name :
see the sample
CONCAT('SELECT `date`,'
,GROUP_CONCAT(f1)
,' FROM YOURTABLE GROUP BY DATE')
INTO #myquery
FROM (
SELECT DISTINCT CONCAT('sum(s_id = ',s_id,') AS sid_',s_id) AS f1
FROM yourtable
) tab1;
-- ONLY for Test to verify the Query
SELECT #myquery;
PREPARE test FROM #myquery;
EXECUTE test;
DEALLOCATE PREPARE test;
sample
mysql> SELECT * FROM yourtable;
+------+------------+
| s_id | date |
+------+------------+
| 1 | 2016-01-01 |
| 1 | 2017-02-02 |
| 2 | 2017-01-05 |
| 4 | 2016-03-04 |
| 7 | 2016-12-12 |
+------+------------+
5 rows in set (0,01 sec)
mysql> SELECT
-> CONCAT('SELECT `date`,'
-> ,GROUP_CONCAT(f1)
-> ,' FROM YOURTABLE GROUP BY DATE')
-> INTO #myquery
-> FROM (
-> SELECT DISTINCT CONCAT('sum(s_id = ',s_id,') AS sid_',s_id) AS f1
-> FROM yourtable
-> ) tab1;
Query OK, 1 row affected (0,01 sec)
mysql> SELECT #myquery;
+----------------------------------------------------------------------------------------------------------------------------------------+
| #myquery |
+----------------------------------------------------------------------------------------------------------------------------------------+
| SELECT `date`,sum(s_id = 1) AS sid_1,sum(s_id = 2) AS sid_2,sum(s_id = 4) AS sid_4,sum(s_id = 7) AS sid_7 FROM YOURTABLE GROUP BY DATE |
+----------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)
mysql> PREPARE test FROM #myquery;
Query OK, 0 rows affected (0,00 sec)
mysql> EXECUTE test;
+------------+-------+-------+-------+-------+
| date | sid_1 | sid_2 | sid_4 | sid_7 |
+------------+-------+-------+-------+-------+
| 2016-01-01 | 1 | 0 | 0 | 0 |
| 2016-03-04 | 0 | 0 | 1 | 0 |
| 2016-12-12 | 0 | 0 | 0 | 1 |
| 2017-01-05 | 0 | 1 | 0 | 0 |
| 2017-02-02 | 1 | 0 | 0 | 0 |
+------------+-------+-------+-------+-------+
5 rows in set (0,00 sec)
mysql> DEALLOCATE PREPARE test;
Query OK, 0 rows affected (0,00 sec)
mysql>
I have a 'big' table like this
id user type comment
6 1 A id '3' - #8
7 1 A id '3' - #9
8 3 B
9 3 B
I want to extract the numbers after the hash and join it with the id column to have the following (when the number between the single quotes is equal to the user)
id1 id2 user type
6 8 3 B
7 9 3 B
A create a copy of your table, its name is bigtable and insert those values that you gave us:
mysql> create table bigtable (id int, user_id int, type varchar(10), comment varchar(30));
Query OK, 0 rows affected (0.04 sec)
mysql> insert into bigtable values (6,1, 'A', 'id 3 - #8'),(7,1,'A', 'id 3 - #9'),(8,3, 'B','' ),(9,3, 'B','');
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from bigtable;
+------+---------+------+-----------+
| id | user_id | type | comment |
+------+---------+------+-----------+
| 6 | 1 | A | id 3 - #8 |
| 7 | 1 | A | id 3 - #9 |
| 8 | 3 | B | |
| 9 | 3 | B | |
+------+---------+------+-----------+
4 rows in set (0.00 sec)
I did a self join and use the substrn_index function:
mysql> select b1.id,b2.id,b1.user_id,b1.type
from bigtable as b1 join bigtable as b2
on b1.id=SUBSTRING_INDEX(b2.COMMENT,'#',-1);
+------+------+---------+------+
| id | id | user_id | type |
+------+------+---------+------+
| 8 | 6 | 3 | B |
| 9 | 7 | 3 | B |
+------+------+---------+------+
2 rows in set (0.00 sec)
I hope this helped you
I have a table with different values for different countries, for example:
id| country | value
===================
1 | Argelia | 8
2 | USA | 10
1 | China | 12
1 | Italy | 13
I am interested in only one country and the total, but I'm having trouble coming up with a single query to do it. The result of this query for id 1 would be:
id| value_in_Italy | total
==========================
1 | 13 | 33
As you can see, I obtained the value for Italy, and the total value. What kind of query would produce rows like the above for a similar table?
Here is the query you need:
select id,SUM(IF(country='Italy',value,0)) italy_value,SUM(value) id_values
from countrydata where id = 1;
Here is your sample data:
drop database if exists luqita;
create database luqita;
use luqita
create table countrydata
(
id int not null,
country varchar(32),
value int not null
);
insert into countrydata values
(1,'Argelia', 8 ),(2,'USA' , 10 ),
(1,'China' , 12 ),(1,'Italy' , 13 );
select * from countrydata;
Here is your sample data loaded:
mysql> drop database if exists luqita;
Query OK, 1 row affected (0.03 sec)
mysql> create database luqita;
Query OK, 1 row affected (0.02 sec)
mysql> use luqita
Database changed
mysql> create table countrydata
-> (
-> id int not null,
-> country varchar(32),
-> value int not null
-> );
Query OK, 0 rows affected (0.12 sec)
mysql> insert into countrydata values
-> (1,'Argelia', 8 ),(2,'USA' , 10 ),
-> (1,'China' , 12 ),(1,'Italy' , 13 );
Query OK, 4 rows affected (0.05 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from countrydata;
+----+---------+-------+
| id | country | value |
+----+---------+-------+
| 1 | Argelia | 8 |
| 2 | USA | 10 |
| 1 | China | 12 |
| 1 | Italy | 13 |
+----+---------+-------+
4 rows in set (0.00 sec)
mysql>
Here is the proposed query executed:
mysql> select id,SUM(IF(country='Italy',value,0)) italy_value,SUM(value) id_values
-> from countrydata where id = 1;
+----+-------------+-----------+
| id | italy_value | id_values |
+----+-------------+-----------+
| 1 | 13 | 33 |
+----+-------------+-----------+
1 row in set (0.00 sec)
mysql>
Now, if you want to run this query against all rows at the same time, try this all-inclusive query:
select
B.id,
SUM(IF(A.country=B.country,B.value,0)) country_value,
SUM(IF(A.id=B.id,A.value,0)) id_values
from
countrydata A,
countrydata B
group by B.country;
Here is that all-inclusive query execute
mysql> select
-> B.id,
-> SUM(IF(A.country=B.country,B.value,0)) country_value,
-> SUM(IF(A.id=B.id,A.value,0)) id_values
-> from
-> countrydata A,
-> countrydata B
-> group by B.country;
+----+---------------+-----------+
| id | country_value | id_values |
+----+---------------+-----------+
| 1 | 8 | 33 |
| 1 | 12 | 33 |
| 1 | 13 | 33 |
| 2 | 10 | 10 |
+----+---------------+-----------+
4 rows in set (0.00 sec)
mysql>
Give it a Try !!!