MariaDB, PBXT and mysterious query results - mariadb

First of all, here's the table:
CREATE TABLE `outlet_tags` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`importer_id` int(11) NOT NULL,
`outlet_id` int(11) NOT NULL,
`code` varchar(20) NOT NULL,
`postcode` varchar(15) DEFAULT NULL,
`tag_set` varchar(45) DEFAULT NULL,
`tag_type` varchar(45) DEFAULT NULL,
`tag_details` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_report_outlet_tags_1` (`importer_id`),
KEY `fk_report_outlet_tags_2` (`outlet_id`),
KEY `outlet_tag_set` (`tag_set`),
KEY `outlet_tag_type` (`tag_type`),
KEY `outlet_tag_details` (`tag_details`),
CONSTRAINT `fk_report_outlet_tags_1` FOREIGN KEY (`importer_id`) REFERENCES `importers` (`id`),
CONSTRAINT `fk_report_outlet_tags_2` FOREIGN KEY (`outlet_id`) REFERENCES `outlets` (`id`)
) ENGINE=PBXT DEFAULT CHARSET=utf8;
Can anyone shed any light on why the field values change depending upon the conditions used in the following queries? It doesn't happen if the engine is Maria.
select * from outlet_tags where code=1503 and outlet_id=407 limit 3;
+------+-------------+-----------+------+----------+---------+-----------------+----------------+
| id | importer_id | outlet_id | code | postcode | tag_set | tag_type | tag_details |
+------+-------------+-----------+------+----------+---------+-----------------+----------------+
| 222 | 1 | 407 | 1503 | XXX XXX | outlet | Make up | Make up |
| 675 | 1 | 407 | 1503 | XXX XXX | outlet | Approved Status | Approved |
| 1619 | 1 | 407 | 1503 | XXX XXX | outlet | Retail Area | No Retail Area |
+------+-------------+-----------+------+----------+---------+-----------------+----------------+
3 rows in set (0.00 sec)
select * from outlet_tags where code=1503 and importer_id=1 limit 3;
+------+-------------+-----------+------+----------+---------+-----------------+----------------+
| id | importer_id | outlet_id | code | postcode | tag_set | tag_type | tag_details |
+------+-------------+-----------+------+----------+---------+-----------------+----------------+
| 222 | 1 | 407 | 1503 | XXX XXX | outlet | Make up | Make up |
| 675 | 1 | 407 | 1503 | XXX XXX | outlet | Approved Status | Approved |
| 1619 | 1 | 407 | 1503 | XXX XXX | outlet | Retail Area | No Retail Area |
+------+-------------+-----------+------+----------+---------+-----------------+----------------+
3 rows in set (0.00 sec)
select * from outlet_tags where importer_id=1 and outlet_id=407 limit 3;
+------+-------------+-----------+------+----------+---------+----------+-------------+
| id | importer_id | outlet_id | code | postcode | tag_set | tag_type | tag_details |
+------+-------------+-----------+------+----------+---------+----------+-------------+
| 222 | 1 | 407 | 1503 | NULL | NULL | NULL | NULL |
| 675 | 1 | 407 | 1503 | NULL | NULL | NULL | NULL |
| 1619 | 1 | 407 | 1503 | NULL | NULL | NULL | NULL |
+------+-------------+-----------+------+----------+---------+----------+-------------+
3 rows in set (0.00 sec)
Update: as of MariaDB 5.5 PBXT was dropped as a storage engine

Try using an ORDER BY with the queries.
Different engines may return rows in different order depending on how the rows are retrieved.

Related

change column type and convert the existing values from string to integer in mariadb

I have a table name employees
MariaDB [company]> describe employees;
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| employee_id | char(10) | NO | | NULL | |
| first_name | varchar(20) | NO | | NULL | |
| last_name | varchar(20) | NO | | NULL | |
| email | varchar(60) | NO | | NULL | |
| phone_number | char(14) | NO | | NULL | |
| hire_date | date | NO | | NULL | |
| job_id | int(11) | NO | | NULL | |
| salary | varchar(30) | NO | | NULL | |
| commission_pct | char(10) | NO | | NULL | |
| manager_id | char(10) | NO | | NULL | |
| department_id | char(10) | NO | | NULL | |
+----------------+-------------+------+-----+---------+-------+
MariaDB [company]> select * from employees;
+-------------+-------------+-------------+--------------------+---------------+------------+--------+----------+----------------+------------+---------------+
| employee_id | first_name | last_name | email | phone_number | hire_date | job_id | salary | commission_pct | manager_id | department_id |
+-------------+-------------+-------------+--------------------+---------------+------------+--------+----------+----------------+------------+---------------+
| 100 | Steven | King | sking#gmail.com | 515.123.4567 | 2003-06-17 | 1 | 24000.00 | 0.00 | 0 | 90 |
| 101 | Neena | Kochhar | nkochhar#gmail.com | 515.123.4568 | 2005-09-21 | 2 | 17000.00 | 0.00 | 100 | 90 |
| 102 | Lex | Wow | Lwow#gmail.com | 515.123.4569 | 2001-01-13 | 2 | 17000.00 | 0.00 | 100 | 9 |
| 103 | Alexander | Hunold | ahunold#gmail.com | 590.423.4567 | 2006-01-03 | 3 | 9000.00 | 0.00 | 102 | 60 |
| 104 | Bruce | Ernst | bernst#gmail.com | 590.423.4568 | 2007-05-21 | 3 | 6000.00 | 0.00 | 103 | 60 |
| 105 | David | Austin | daustin#gmail.com | 590.423.4569 | 2005-06-25 | 3 | 4800.00 | 0.00 | 103 | 60 |
| 106 | Valli | Pataballa | vpatabal#gmail.com | 590.423.4560 | 2006-02-05 | 3 | 4800.00 | 0.00 | 103 | 60 |
| 107 | Diana | Lorentz | dlorentz#gmail.com | 590.423.5567 | 2007-02-07 | 3 | 4200.00 | 0.00 | 103 | 60 |
| 108 | Nancy | Greenberg | ngreenbe#gmail.com | 515.124.4569 | 2002-08-17 | 4 | 12008.00 | 0.00 | 101 | 100 |
| 109 | Daniel | Faviet | dfaviet#gmail.com | 515.124.4169 | 2002-08-16 | 5 | 9000.00 | 0.00 | 108 | 100 |
| 110 | John | Chen | jchen#gmail.com | 515.124.4269 | 2005-09-28 | 5 | 8200.00 | 0.00 | 108 | 100 |
| 111 | Ismael | Sciarra | isciarra#gmail.com | 515.124.4369 | 2005-09-30 | 5 | 7700.00 | 0.00 | 108 | 100 |
| 112 | Jose | Urman | jurman#gmail.com | 515.124.4469 | 2006-03-07 | 5 | 7800.00 | 0.00 | 108 | 100 |
| 113 | Luis | Popp | lpopp#gmail.com | 515.124.4567 | 2007-12-07 | 5 | 6900.00 | 0.00 | 108 | 100 |
| 114 | Den | Raphaely | drapheal#gmail.com | 515.127.4561 | 2002-12-07 | 6 | 11000.00 | 0.00 | 100 | 30 |
| 115 | Alexander | Khoo | akhoo#gmail.com | 515.127.4562 | 2003-05-18 | 7 | 3100.00 | 0.00 | 114 | 30 |
+-------------+-------------+-------------+--------------------+---------------+------------+--------+----------+----------------+------------+---------------+
I wanted to change the salary column from string to integer. So, I ran this command
MariaDB [company]> alter table employees modify column salary int;
ERROR 1292 (22007): Truncated incorrect INTEGER value: '24000.00'
As you can see it gave me truncation error. I found some previous questions where they showed how to use convert() and trim() but those actually didn't answer my question.
sql code and data can be found here https://0x0.st/oYoB.com_5zfu
I tested this on MySQL and it worked fine. So it is apparently an issue only with MariaDB.
The problem is that a string like '24000.00' is not an integer. Integers don't have a decimal place. So in strict mode, the implicit type conversion fails.
I was able to work around this by running this update first:
update employees set salary = round(salary);
The column is still a string, but '24000.00' has been changed to '24000' (with no decimal point character or following digits).
Then you can alter the data type, and implicit type conversion to integer works:
alter table employees modify column salary int;
See demonstration using MariaDB 10.6:
https://dbfiddle.uk/V6LrEMKt
P.S.: You misspelled the column name "commission_pct" as "comission_pct" in your sample DDL, and I had to edit that to test. In the future, please use one of the db fiddle sites to share samples, because they will test your code.

Order by bigint myisam is not ordered. Why?

I had to use bigint instead of regular int. After creating the new table it bahaves unusual. See details below.
MariaDB [user]> select * from dmn_base2 ORDER BY id DESC limit 4;
+------------+-----------------------+----------------+--------+
| id | domain | base | tld_id |
+------------+-----------------------+----------------+--------+
| 1975224411 | bank-3dsecure.com | bank-3dsecure | 4 |
| 466015797 | bank-365.se | bank-365 | 378 |
| 1711908528 | bank-2projects.online | bank-2projects | 20 |
| 27739599 | bank-2580.com | bank-2580 | 4 |
+------------+-----------------------+----------------+--------+
^----this is unusual
It uses index:
MariaDB [user]> explain select * from dmn_base2 ORDER BY id DESC limit 4;
+------+-------------+-----------+-------+---------------+---------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------+---------------+---------+---------+------+------+-------+
| 1 | SIMPLE | dmn_base2 | index | NULL | PRIMARY | 8 | NULL | 4 | |
+------+-------------+-----------+-------+---------------+---------+---------+------+------+-------+
Structure of the table:
MariaDB [user]> show columns from dmn_base2;
+--------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| domain | varchar(100) | NO | UNI | NULL | |
| base | varchar(100) | NO | MUL | NULL | |
| tld_id | int(11) | NO | MUL | NULL | |
+--------+--------------+------+-----+---------+-------+
MariaDB [capturesipbee]> SHOW CREATE TABLE dmn_base2;
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| dmn_base2 | CREATE TABLE `dmn_base2` (
`id` bigint(20) NOT NULL,
`domain` varchar(100) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
`base` varchar(100) COLLATE utf8mb4_bin NOT NULL,
`tld_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `domain` (`domain`),
KEY `base` (`base`),
KEY `tld_id` (`tld_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC |
+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Indexes:
MariaDB [user]> show indexes from dmn_base2;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| dmn_base2 | 0 | PRIMARY | 1 | id | A | 460592774 | NULL | NULL | | BTREE | | |
| dmn_base2 | 0 | domain | 1 | domain | A | 460592774 | NULL | NULL | | BTREE | | |
| dmn_base2 | 1 | base | 1 | base | A | 460592774 | NULL | NULL | | BTREE | | |
| dmn_base2 | 1 | tld_id | 1 | tld_id | A | 1967 | NULL | NULL | | BTREE | | |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
query does not finished, killing has no effect after 5 hours
+------+-------+-----------+----+---------+-------+--------------+-----------------------------------------------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+------+-------+-----------+----+---------+-------+--------------+-----------------------------------------------------------+----------+
| 36 | root | localhost | db | Killed | 21107 | Sending data | select * from dmn_base2 ORDER BY id DESC limit 5 | 0.000 |
my guess is: broken index file?
I have copied the database to other device. The same query works as expected.
mysql> select * from dmn_base order by id desc limit 4;
+------------+----------------------+-------------------+--------+
| id | domain | base | tld_id |
+------------+----------------------+-------------------+--------+
| 2147483647 | naturleckerlies.de | naturleckerlies | 921 |
| 2147475178 | meinlohne.de | meinlohne | 921 |
| 2147471022 | mamis-zeit.de | mamis-zeit | 921 |
| 2147456303 | kinderpact-berlin.de | kinderpact-berlin | 921 |
+------------+----------------------+-------------------+--------+
4 rows in set (0.00 sec)
I had to update MariaDB. (10.1->10-6)
As I use Plesk I refer to this articles:
Which MariaDB versions are supported by Plesk?
Upgrade guide

How to merge records based on consective fields in Teradata

I have a source like below table:
+---------+--+--------+--+---------+--+--+------+
| ID | | SEQ_NO | | UNIT_ID | | | D_ID |
+---------+--+--------+--+---------+--+--+------+
| 7979092 | | 1 | | 99 | | | 759 |
| 7979092 | | 2 | | -1 | | | 869 |
| 7979092 | | 3 | | -1 | | | 927 |
| 7979092 | | 4 | | -1 | | | 812 |
| 7979092 | | 5 | | 99 | | | 900 |
| 7979092 | | 6 | | 99 | | | 891 |
| 7979092 | | 7 | | -1 | | | 785 |
| 7979092 | | 8 | | -1 | | | 762 |
| 7979092 | | 9 | | -1 | | | 923 |
+---------+--+--------+--+---------+--+--+------+
I have to merge the rows when consecutive unit_id has same value. We should take max(D_id) when we consolidate the rows. Expected output is:
+---------+---------+------+
| ID | UNIT_ID | D_ID |
+---------+---------+------+
| 7979092 | 99 | 759 |
| 7979092 | -1 | 927 |
| 7979092 | 99 | 900 |
| 7979092 | -1 | 923 |
+---------+---------+------+
I have tried to find the solution using Teradata ordered analytical function, but did not find the solution. I use Teradata 16.
Thank You.
This logic is a bit quirky, it's based on two sequences created by different sort orders:
SELECT
ID
,UNIT_ID
,Max(D_ID)
FROM
(
SELECT
ID
,SEQ_NO
,UNIT_ID
,D_ID
-- assign the same value to consecutive UNIT_IDs
,SEQ_NO -
Row_Number()
Over(PARTITION BY ID, UNIT_ID
ORDER BY SEQ_NO) AS grp
FROM tab
) AS dt
GROUP BY 1,2,grp
You can use RESET WHEN to dynamically create groups within the window. Here's one way to do it:
select ID, UNIT_ID,
max(D_ID) over(
partition by ID order by SEQ_NO
reset when UNIT_ID <> UNIT_ID_prev -- Create new group for new value
) as D_ID
from (
select ID, SEQ_NO, UNIT_ID, D_ID,
lag(UNIT_ID) over(partition by ID order by SEQ_NO) as UNIT_ID_prev -- Previous value
from MY_TABLE
) src
qualify row_number() over(
partition by ID order by SEQ_NO
reset when UNIT_ID <> UNIT_ID_prev -- Match original max() window
) = 1 -- One row per group (similar to DISTINCT)

How to select sqlite columns based on a row lookup

I'm trying to compose an SQLite query and I've found a problem that's beyond my skillset. I'm trying to output columns that are based on the rows of another referenced table.
Food_List:
| food_id | name |
|---------|-----------|
| 1 | Apple |
| 2 | Orange |
| 3 | Pear |
Nutrient_Definition:
| nutrient_id | name |
|-------------|-----------|
| 21 | Carbs |
| 22 | Protein |
| 23 | Fat |
Nutrient_Data:
| food_id | nutrient_id | value |
|---------|-------------|-------|
| 1 | 21 | 50 |
| 1 | 22 | 24 |
| 1 | 23 | 63 |
| 2 | 22 | 12 |
| 2 | 23 | 95 |
| 3 | 21 | 66 |
| 3 | 22 | 87 |
| 3 | 23 | 38 |
Output:
| food_id | name | Carbs | Protein | Fat |
|---------|-----------|-------|---------|-----|
| 1 | Apple | 50 | 24 | 63 |
| 2 | Orange | | 12 | 95 |
| 3 | Pear | 66 | 87 | 38 |
(Note that Orange does not have a "Carbs" entry in the Nutrient_Data table)
I believe the following will do what you want :-
DROP TABLE IF EXISTS food_list;
CREATE TABLE IF NOT EXISTS food_list(food_id INTEGER PRIMARY KEY, name TEXT);
DROP TABLE IF EXISTS nutrient_definition;
CREATE TABLE IF NOT EXISTS nutrient_definition(nutrient_id INTEGER PRIMARY KEY, name TEXT);
DROP TABLE IF EXISTS nutrient_data;
CREATE TABLE IF NOT EXISTS nutrient_data(food_id INTEGER, nutrient_id INTEGER, value INTEGER);
INSERT INTO food_list (name) VALUES
('apple'),('orange'),('pear')
;
INSERT INTO nutrient_definition (name) VALUES
('carbs'),('protien'),('fat')
;
INSERT INTO nutrient_data VALUES
(1,1,50),(1,2,24),(1,3,63),
(2,2,12),(2,3,95),
(3,1,66),(3,2,87),(3,3,38)
;
SELECT food_list.food_id,food_list.name,
(
SELECT value
FROM nutrient_data
WHERE nutrient_data.food_id = food_list.food_id AND
nutrient_data.nutrient_id = (SELECT nutrient_definition.nutrient_id FROM nutrient_definition WHERE nutrient_definition.name = 'carbs')
),
(
SELECT value
FROM nutrient_data
WHERE nutrient_data.food_id = food_list.food_id AND
nutrient_data.nutrient_id = (SELECT nutrient_definition.nutrient_id FROM nutrient_definition WHERE nutrient_definition.name = 'protien')
),
(
SELECT value
FROM nutrient_data
WHERE nutrient_data.food_id = food_list.food_id AND
nutrient_data.nutrient_id = (SELECT nutrient_definition.nutrient_id FROM nutrient_definition WHERE nutrient_definition.name = 'fat')
)
FROM food_list
;
Results in :-

Add columns from file to an existing table in MariaDB 10.1

I want to add a new column from a file to an existing table, in the way cbind does in R.
The file has 1 column, 23710 lines, all numbers:
me#my_server:/var/www/html/my_website$ head my_sample.txt
61
66
0
330
76
9
10
16
6
0
Using the code:
ALTER TABLE my_table ADD COLUMN IF NOT EXISTS sample69 INT(10) DEFAULT NULL;
LOAD DATA LOCAL INFILE '/var/www/html/my_website/my_sample.txt' INTO TABLE my_table LINES TERMINATED BY '\n' (sample69);
Before:
MariaDB [my_database]> select * from my_table limit 10;
+------------+-----------+
| geneSymbol | sample000 |
+------------+-----------+
| A1BG | 61 |
| A1BG-AS1 | 66 |
| A1CF | 0 |
| A2M | 330 |
| A2M-AS1 | 76 |
| A2ML1 | 9 |
| A2MP1 | 10 |
| A4GALT | 16 |
| A4GNT | 6 |
| AA06 | 0 |
+------------+-----------+
MariaDB [my_database]> select count(*) from my_table;
+----------+
| count(*) |
+----------+
| 23710 |
+----------+
After:
MariaDB [my_database]> select * from my_table limit 10;
+------------+-----------+-----------+
| geneSymbol | sample000 | sample69 |
+------------+-----------+-----------+
| A1BG | 61 | NULL |
| A1BG-AS1 | 66 | NULL |
| A1CF | 0 | NULL |
| A2M | 330 | NULL |
| A2M-AS1 | 76 | NULL |
| A2ML1 | 9 | NULL |
| A2MP1 | 10 | NULL |
| A4GALT | 16 | NULL |
| A4GNT | 6 | NULL |
| AA06 | 0 | NULL |
+------------+-----------+-----------+
MariaDB [my_database]> select count(*) from my_table;
+----------+
| count(*) |
+----------+
| 47420 |
+----------+
It apparently appends the data to the end of the column. Instead I want the new column to be the same length of 23710, filled with the new data from the file.
What am I doing wrong?
LOAD only loads whole rows.
Even if it could load just one column, how would it know which row each number goes with?
You must reconstruct the data with two columns (geneSymbol and sample69), load that into a temp table, then do a multi-table JOIN to move the data into the main table.
Addenda
If you have 69 columns of samples, that it the wrong way to design the schema. At some point, you will hit a limit.
Plan A: Lots of rows, not lots of columns:
CREATE TABLE x (
geneSymbol VARCHAR(..) ...,
num SMALLINT UNSIGNED NOT NULL,
value SMALLINT UNSIGNED NOT NULL,
PRIMARY KEY(geneSymbol, num)
) ENGINE=InnoDB
Plan B (This will require code to add each new sample):
CREATE TABLE x (
geneSymbol VARCHAR(..) ...,
text NOT NULL, -- JSON encoded list of samples for that gene
PRIMARY KEY(geneSymbol)
) ENGINE=InnoDB
Plan C (aimed at reading one sample):
CREATE TABLE x (
num SMALLINT UNSIGNED NOT NULL,
text NOT NULL, -- JSON encoded list of values for that sample
PRIMARY KEY(num)
) ENGINE=InnoDB
What will your queries be like? I suspect you will be reading all the data, not doing any WHERE clauses based on symbol or num??

Resources