mysql join extracted number - 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

Related

Limit with not operator is not working correctly MySql

I am using a query as below with not operator in where and limit. I am not able get correct sequencing of data (Without limit clause it is different and with limit ordering of data is something different).
SELECT DISTINCT(id) FROM `table` WHERE (1 AND id_type!=1) ORDER BY id desc LIMIT 2
Table Structure with sample data:
id id_type
1 1
2 1
3 2
4 3
5 3
6 3
Any Suggestions ?
Expected Output :
6
5
But When I remove the limit ordering is not same :
5
6
4
3
2
Note: This is just an sample data structure. Original table is contains much fields and different columns.
Maybe there is no problem at all. See this.
MariaDB [fbb]> SELECT * FROM `test`;
+----+---------+
| id | id_type |
+----+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 5 | 3 |
| 6 | 3 |
+----+---------+
6 rows in set (0.00 sec)
MariaDB [fbb]> SELECT DISTINCT(id) FROM `test` WHERE (1 AND id_type!=1) ORDER BY id desc LIMIT 2;
+----+
| id |
+----+
| 6 |
| 5 |
+----+
2 rows in set (0.00 sec)
MariaDB [fbb]>

MYSQL: How to fill null values in column with the previous entry?

I've got a program at work that exports to CSV but leaves blanks in the most irritable places. I want to view the carrier and destination on the same row and currently the carrier is 1 row above the destination like below:
I have a database that is like the following:
|Key|Carrier ||Destination|
|-------------------------|
| 1 | HULL2 || |
| 2 | || C14A102 |
| 3 | DONC1 || |
| 4 | || D15A012 |
What I want:
|Key|Carrier ||Destination|
|-------------------------|
| 1 | HULL2 || |
| 2 | HULL2 || C14A102 |
| 3 | DONC1 || |
| 4 | DONC1 || D15A012 |
Either that or insert a new column with the information from carrier column.
Sorry if this is confusing its confusing me to explain it!
James
Here is a solution, by cloning another table and then deleting it:
CREATE TABLE t1(Key_id INT PRIMARY KEY, Carrier CHAR(20), Destination CHAR(20));
INSERT INTO t1 VALUES(1, 'HULL2', ''),(2,'','C14A102'),(3,'DONC1',''),(4,'','D15A012');
CREATE TABLE t2 LIKE t1;
INSERT INTO t2 SELECT * FROM t1;
SELECT * FROM t1;
UPDATE t1 SET Carrier =
(
SELECT t2.Carrier
FROM t2
WHERE t2.Key_id < t1.Key_id AND t2.Carrier != ''
ORDER BY t2.Key_id DESC
LIMIT 1
)
WHERE Carrier = '';
SELECT * FROM t1;
DROP TABLE t2;
Output:
mysql> SELECT * FROM t1;
+--------+---------+-------------+
| Key_id | Carrier | Destination |
+--------+---------+-------------+
| 1 | HULL2 | |
| 2 | | C14A102 |
| 3 | DONC1 | |
| 4 | | D15A012 |
+--------+---------+-------------+
4 rows in set (0.00 sec)
mysql> UPDATE t1 SET Carrier =
-> (
-> SELECT t2.Carrier
-> FROM t2
-> WHERE t2.Key_id < t1.Key_id AND t2.Carrier != ''
-> ORDER BY t2.Key_id DESC
-> LIMIT 1
-> )
-> WHERE Carrier = '';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> SELECT * FROM t1;
+--------+---------+-------------+
| Key_id | Carrier | Destination |
+--------+---------+-------------+
| 1 | HULL2 | |
| 2 | HULL2 | C14A102 |
| 3 | DONC1 | |
| 4 | DONC1 | D15A012 |
+--------+---------+-------------+
4 rows in set (0.00 sec)
Assuming that the column 'key' can be trusted in this way, I would update with a self join where the join uses key = key+1, and then make sure it's only affecting even rows.
UPDATE tablename as even_row JOIN tablename as odd_row
ON even_row.Key = odd_row.Key + 1
SET even_row.Carrier = odd_row.Carrier
WHERE odd_row.Key % 2;

Make new column which is incremented by it's order

I need to make new column for my table Products -> called Order (new column). And using rails migration I need to add new column and instantly set it's order number, but it's need to be done by product_id.
What I mean I need something like:
product_id | order
1 ------------> 1
1 ------------> 2
1 ------------> 3
2 ------------> 1
2 ------------> 2
Is there a way of doing it?
EDIT :
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''order' = t1.'order'' at line 15:
update product_submissions t
join (
select
id,
product_id,
'order' from (
select id,
product_id,
#rn:= if(#prev = product_id,#rn:=#rn+1,1) as 'order',
#prev:=product_id
from product_submissions,
(select #rn:=0,#prev:=0)r
order by product_id,id
)x
)t1 on t1.id=t.id set t.'order' = t1.'order'
Consider the following
mysql> create table test (id int ,product_id int);
Query OK, 0 rows affected (0.14 sec)
mysql> insert into test values (1,1),(2,1),(3,1),(4,2),(5,2);
Now lets create the order
select
product_id,
`order` from (
select
product_id,
#rn:= if(#prev = product_id,#rn:=#rn+1,1) as `order`,
#prev:=product_id from test,(select #rn:=0,#prev:=0)r
order by product_id,id
)x ;
This will give you something as
+------------+-------+
| product_id | order |
+------------+-------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
+------------+-------+
Now lets use in update command, but before that lets add the column (in your case its already there)
mysql> alter table test add column `order` int ;
Query OK, 5 rows affected (0.29 sec)
mysql> select * from test ;
+------+------------+-------+
| id | product_id | order |
+------+------------+-------+
| 1 | 1 | NULL |
| 2 | 1 | NULL |
| 3 | 1 | NULL |
| 4 | 2 | NULL |
| 5 | 2 | NULL |
+------+------------+-------+
5 rows in set (0.00 sec)
Finally the update command
update test t
join (
select
id,
product_id,
`order` from (
select id,
product_id,
#rn:= if(#prev = product_id,#rn:=#rn+1,1) as `order`,
#prev:=product_id
from test,(select #rn:=0,#prev:=0)r
order by product_id,id
)x
)t1 on t1.id=t.id set t.`order` = t1.`order`
mysql> select * from test ;
+------+------------+-------+
| id | product_id | order |
+------+------------+-------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
+------+------------+-------+
5 rows in set (0.00 sec)

Mysql Group by second column if first column is equal?

I have a table that looks like this
id | rating
1 | 1
1 | 3
1 | 1
1 | 2
2 | 3
2 | 3
2 | 1
etc,you get the idea.
Anyway, I want to end up with this result set
id | rating | num
1 | 1 | 2
1 | 3 | 1
1 | 2 | 1
2 | 3 | 2
2 | 1 | 1
So, what I want to do is group the rating's together as long as the id is the same!
I thought I could just do group by id, rating and just assumed it would group only if both columns were the same, but it doesn't it groups if either column is the same so I end up with
id | rating | num
1 | 1 | 7
How can I solve this?
I don't understand the issue you are having. This query works for me:
select
id, rating, COUNT(rating) as num
FROM rating
GROUP BY id, rating
ORDER BY id, rating ASC;
And, just to be thorough, here is my entire test session:
mysql> create table rating (id int, rating int);
Query OK, 0 rows affected (0.04 sec)
mysql> insert into rating values (1,1),(1,3),(1,1),(1,2),(2,3),(2,3),(2,1);
Query OK, 7 rows affected (0.00 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> select id, rating, COUNT(rating) as num FROM rating GROUP BY id, rating;
+------+--------+-----+
| id | rating | num |
+------+--------+-----+
| 1 | 1 | 2 |
| 1 | 2 | 1 |
| 1 | 3 | 1 |
| 2 | 1 | 1 |
| 2 | 3 | 2 |
+------+--------+-----+
5 rows in set (0.00 sec)
you could try
SELECT id,rating,COUNT(rating) AS num
FROM table1
GROUP BY id,rating
ORDER BY id ASC
SQLFiddle Demo
SELECT id,rating,count(rating) from table group by id,rating

Selecting total value, and a subset of it

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 !!!