I have succesfully created a database in mySQL using the commandline and imported some data. It currently looks like this..
desc data;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| code | varchar(10) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
SELECT * FROM data;
+----+----------+
| id | code |
+----+----------+
| 1 | 123abc
| 2 | 234def
| 3 | 567ghi
| 4 | 890jkl
I would like to add a column to the table called timestamp, I am doing this with..
alter table data add timestamp VARCHAR(20);
But then my table looks like this...
desc data;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| code | varchar(10) | YES | | NULL | |
| timestamp | varchar(20) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
SELECT * FROM data;
+----+----------+-----------+
| id | code | timestamp |
+----+----------+-----------+
| NULL |
| NULL |
| NULL |
| NULL |
Where am I going wrong?
here you can see the backticks
alter table `data` add `timestamp` VARCHAR(20);
SAMPLE
MariaDB []> desc data;
+-------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| e | enum('x1','x2','x3') | YES | | NULL | |
+-------+----------------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
MariaDB []> alter table `data` add `timestamp` VARCHAR(20);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB []> desc data;
+-----------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| e | enum('x1','x2','x3') | YES | | NULL | |
| timestamp | varchar(20) | YES | | NULL | |
+-----------+----------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
Table Data
MariaDB [who]> select * from `data`;
+----+------+-----------+
| id | e | timestamp |
+----+------+-----------+
| 1 | x1 | NULL |
| 2 | x2 | NULL |
+----+------+-----------+
2 rows in set (0.00 sec)
MariaDB [who]>
Related
Query #1:
SELECT SUM(size)
FROM RepoSize s
LEFT JOIN VirtualRepo v ON s.repo_id = v.repo_id
WHERE v.repo_id IS NULL;
+----------------+
| SUM(size) |
+----------------+
| 61550890457198 |
+----------------+
1 row in set (0.32 sec)
Query #2:
SELECT SUM(size)
FROM RepoSize
WHERE repo_id NOT IN (SELECT repo_id FROM VirtualRepo);
+----------------+
| SUM(size) |
+----------------+
| 61551148262106 |
+----------------+
1 row in set (0.45 sec)
I thought the 2 SQL queries would return the same result, but the truth is the second value is larger than the first, repo_id is the primary key in both tables.
table structure:
mysql> desc RepoSize;
+---------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+-------+
| repo_id | char(37) | NO | PRI | NULL | |
| size | bigint(20) unsigned | YES | | NULL | |
| head_id | char(41) | YES | | NULL | |
+---------+---------------------+------+-----+---------+-------+
mysql> desc VirtualRepo;
+-------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+-------+
| repo_id | char(36) | NO | PRI | NULL | |
| origin_repo | char(36) | YES | MUL | NULL | |
| path | text | YES | | NULL | |
| base_commit | char(40) | YES | | NULL | |
+-------------+----------+------+-----+---------+-------+
As repo_id is primary key in both the tables, there is not a possibility of difference because of nulls in the field. So ideally both the queries should give the same result unless the data has changed in between the execution. So most probably the difference is because of change in data in between.
So I'm struggling with this very (very) basic MySQL query which is supposed to retrieve courrier records ordered by number of joined reactions.
I have this table:
mysql> describe courrier;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| envoi | datetime | NO | | NULL | |
| intro | longtext | NO | | NULL | |
| courrier | longtext | NO | | NULL | |
| slug | varchar(255) | NO | | NULL | |
| categorie_id | int(11) | YES | MUL | NULL | |
| reponse | longtext | YES | | NULL | |
| recu | datetime | YES | | NULL | |
| published | tinyint(1) | NO | | NULL | |
| image_id | int(11) | YES | UNI | NULL | |
| like_count | int(11) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
12 rows in set (0.02 sec)
Which has:
mysql> select count(id) from courrier;
+-----------+
| count(id) |
+-----------+
| 56 |
+-----------+
1 row in set (0.00 sec)
Joined with:
mysql> describe reaction;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| courrier_id | int(11) | YES | MUL | NULL | |
| date | datetime | NO | | NULL | |
| ip | varchar(15) | NO | | NULL | |
| reaction | longtext | NO | | NULL | |
| url | varchar(255) | YES | | NULL | |
| name | varchar(255) | NO | | NULL | |
| status | int(11) | NO | | NULL | |
| email | varchar(255) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
9 rows in set (0.01 sec)
Which has:
mysql> select count(id) from reaction;
+-----------+
| count(id) |
+-----------+
| 236 |
+-----------+
1 row in set (0.00 sec)
On: ALTER TABLE reaction ADD CONSTRAINT FK_5DA165A18BF41DC7 FOREIGN KEY (courrier_id) REFERENCES courrier (id);
(backticks removed for readability)
So when I run this query:
SELECT c0_.id AS id_0,
c0_.name AS name_1,
c0_.slug AS slug_2,
c0_.envoi AS envoi_3,
c0_.intro AS intro_4,
c0_.courrier AS courrier_5,
c0_.reponse AS reponse_6,
c0_.published AS published_7,
c0_.like_count AS like_count_8,
c0_.recu AS recu_9,
COUNT(r1_.id) AS sclr_10,
c0_.image_id AS image_id_11,
c0_.categorie_id AS categorie_id_12
FROM courrier c0_
INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id
ORDER BY sclr_10 DESC LIMIT 25
I'm quite naturally expecting to be provided with one row per record in courrier along with a additional column specifying the number of joined reaction records.
But I'm returned: 1 row in set (0.03 sec). It's the first record inserted in courrier and the additional column is filled with the number 242.
What did I do wrong?
You should use a group by clause, otherwise the count will aggregate the whole result set:
SELECT c0_.id AS id_0 /*, ...*/,
COUNT(r1_.id) AS sclr_10
FROM courrier c0_
INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id
GROUP BY c0_.id
ORDER BY sclr_10 DESC
LIMIT 25
Note: if you are also interested in courrier records that have no corresponding record in reaction (count = 0), then use LEFT JOIN instead of INNER JOIN.
How can I select all rows from the 'trade' table that have a 'ticker_id' field equal to the 'id' field of a row from the 'ticker' table, that has a 'name' field equal to 'MSFT'?
The 'trade.ticker_id' field is a foreign key to the 'ticker.id' field.
Is this a bad design if I want filter a lot of 'trade' rows?
mysql> describe ticker;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | NO | | NULL | |
| long_name | varchar(250) | YES | | NULL | |
| exchange_id | int(11) | YES | MUL | NULL | |
+-------------+--------------+------+-----+---------+----------------+
4 rows in set (0,00 sec)
mysql> describe trade;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| time | datetime | NO | | NULL | |
| price | float | NO | | NULL | |
| quantity | int(11) | NO | | NULL | |
| source | varchar(64) | YES | | NULL | |
| buyer | varchar(64) | YES | | NULL | |
| seller | varchar(64) | YES | | NULL | |
| initiator | varchar(64) | YES | | NULL | |
| ticker_id | int(11) | YES | MUL | NULL | |
+-----------+-------------+------+-----+---------+----------------+
9 rows in set (0,00 sec)
SELECT * FROM trade TR
LEFT JOIN ticker TI ON TR.ticker_id = TI.id
WHERE TI.name = "MSFT"
I had asked a question here on how to get a sql function(max) result into a #variable and how to use it. The answer I got was very straightforward and useful(tanx to the responder: Tom Mac). No I am using the same mechanism in my program and I get an unacceptable result that I'll explain here:
Please Have a look at my mysql console and everything is self explanatory. Even my question :) :
> mysql> select max(command_idx) into #max_command_idx from command;
> Query OK, 1 row affected (0.00 sec)
Now use the variable for the first time:
mysql> insert into command(controller_idx,subcontroller_idx,command_idx,controller_id, subcontroller_id,code,status,type,plan_name,timetable_id,offset,ctime,user_name,result) values
(0,0,#max_command_idx+1,'937','SUB0','SMS',0,'CONFIG','NA','NA',0,NOW(),'admin',0);
Query OK, 1 row affected (0.00 sec)
Now use the variable for the second time for another table:
> mysql> insert into
> csmslist(controller_idx,subcontroller_idx,command_idx,csmslist_idx,phone)
> values(0,0,#max_command_idx+1,0,'+60127929022');ERROR 1048 (23000):
> Column 'command_idx' cannot be null
.......................................................................
My QUESTION:
would you kindly tell me why I get this error?
THANK YOU
.......................................................................
more information on my tables:
mysql> desc csmslist;
+-------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-------------+------+-----+---------+-------+
| controller_idx | int(11) | NO | PRI | NULL | |
| subcontroller_idx | int(11) | NO | PRI | NULL | |
| command_idx | int(11) | NO | PRI | NULL | |
| csmslist_idx | int(11) | NO | PRI | NULL | |
| phone | varchar(24) | YES | | NULL | |
+-------------------+-------------+------+-----+---------+-------+
5 rows in set (0.01 sec)
mysql> desc command;
+-------------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-------------+------+-----+-------------------+-----------------------------+
| controller_idx | int(11) | NO | PRI | NULL | |
| subcontroller_idx | int(11) | NO | PRI | NULL | |
| command_idx | int(11) | NO | PRI | NULL | auto_increment |
| controller_id | varchar(24) | YES | | NULL | |
| subcontroller_id | varchar(24) | YES | | NULL | |
| code | varchar(12) | YES | | NULL | |
| status | int(11) | YES | | NULL | |
| type | varchar(24) | YES | | NULL | |
| plan_name | varchar(24) | YES | | NULL | |
| timetable_id | varchar(24) | YES | | NULL | |
| offset | int(11) | YES | | NULL | |
| ctime | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| user_name | varchar(80) | YES | | NULL | |
| result | int(11) | YES | | NULL | |
+-------------------+-------------+------+-----+-------------------+-----------------------------+
14 rows in set (0.01 sec)
The command table has an auto_increment, when you set the column to null (which is what you are doing, despite what you think you are doing), it just does an auto increment on it.
The csmslist table has no auto increment so inserting null fails.
Do this instead:
insert into csmslist(controller_idx,subcontroller_idx,command_idx,csmslist_idx,phone)
values(0,0,LAST_INSERT_ID(),0,'+60127929022');ERROR 1048 (23000):
Column 'command_idx' cannot be null
And in the insert to command just make the column NULL and let the database do its thing for you automatically.
It could be the command table is empty, so it's returning NULL for the max.
BTW instead of using a variable you can put that query right in there:
insert into csmslist(controller_idx,subcontroller_idx,command_idx,csmslist_idx,phone)
values(0,0,(select max(command_idx) from command),0,'+60127929022');ERROR 1048 (23000):
Column 'command_idx' cannot be null
We have 4 tables:
mysql> desc Products;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| product_id | int(11) | NO | PRI | NULL | auto_increment |
| product | varchar(30) | NO | | NULL | |
+------------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> desc Vendors;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| vendor_id | int(11) | NO | PRI | NULL | auto_increment |
| vendor | varchar(30) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> desc Prices;
+------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+----------------+
| price_id | int(11) | NO | PRI | NULL | auto_increment |
| vendor_id | int(11) | NO | MUL | NULL | |
| product_id | int(11) | NO | MUL | NULL | |
| price | double | YES | | NULL | |
+------------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> desc Bought;
+------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+----------------+
| bought_id | int(11) | NO | PRI | NULL | auto_increment |
| product_id | int(11) | NO | MUL | NULL | |
| date | date | YES | | NULL | |
| pieces | int(11) | YES | | 1 | |
+------------+---------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
now we need some complex select statements, to get the tables we need:
first table need columns [vendor, product, price, vendors(that offers the product)].
second table should show what was bought between $date1 and $date2 [product, pieces, vendor, price, date]
last table should show what could've been saved in the given time [vendor(the cheapest vendor for the product), product, pcs, price(for one product), sum(price for n products)].
As this wouldnt be complicated enaugh, the resulting tables have to show the names, instead of a key. We were sitting on this the hole day, but none of us have the knowledge to perform needed searches, so any help would be greatly appreciated.
Look into joins for selecting data from multiple tables:
SELECT * FROM Prices LEFT JOIN (Vendors, Products)
ON (Products.product_id=Prices.product_id AND Vendors.vendor_id=Prices.vendor_id)