MySQL - A way to join all found rows in one column - mysql

CREATE TABLE dummy (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
name VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;
and running this query:
SELECT GROUP_CONCAT(`name` SEPARATOR "||") FROM `dummy`
This query joins name column in all rows with || in a single column. BUT, the result is truncated with mysql configuration as explained in mysql manual :
"... result is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024 ..."
Also in manual it is said that this setting can be changed in run time by the following syntax:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Does changing this configuration works in all mysql server environments? If not, how can I achieve the same result without GROUP_CONCAT without limits?
Also, I think that changing the configuration will not solve my problem because I don't know what to set the value of group_concat_max_len because number of rows in dummy table can be any number.
Thanks.

Have you tried using stored procedure to accomplish your task? You can create a temporary table with a single row/column and append to it while fetching rows from your table. In the end just SELECT the single value from the temporary table.
You can find information about stored routines in mysql manual and other places.

Related

Change INT Default value of mysql(phpmyadmin) in mysql version 5.7.2

Currently, I have the MySQL 5.6 version. In this version INT type column will take 0 automatically even by default value is none.
Column = question_status, Type= INT, Default= None
Old query : INSERT INTO tbl_question (question_status) VALUES ('');
Above Query will Run Perfectly on my older version.
Now, I have imported the database into a newer version of MySQL 5.7.2
New query : INSERT INTO tbl_question (question_status) VALUES ('');
Above query is same but it says I have to change the default value of column because column datatype is INT.
if I'll change the default value manually to 0 in the newer version. It will run perfectly.
The problem is I have around 100 tables in a database and many INT Type columns so I cant change default value of every column one by one.
You can select all columns having an INT type with this query:
SELECT * FROM information_schema.columns WHERE table_schema = '<YOUR_DB>' data_type = 'INT'
Then it will be easy to write a simple script for a mass alter.

Truncating a BINARY column in MySQL using ALTER TABLE

I have a MySQL table t with over 150 million rows. One of the columns (c) was a VARCHAR(64) containing a 64-digit hexadecimal number. To save space and make things faster, I wanted to decode the hex and turn it into a BINARY(32) column.
My plan was to use three queries:
ALTER TABLE t CHANGE c c BINARY(64) NOT NULL;
UPDATE t SET c=UNHEX(c);
ALTER TABLE t CHANGE c c BINARY(32) NOT NULL;
The first 2 worked perfectly, but on the 3rd query I'm getting the error:
#1265 - Data truncated for column 'c' at row 1
I understand that I am truncating data, that's exactly what I want. I want to get rid of the 32 0x00 bytes at the end of the BINARY(64) to turn it into a BINARY(32).
Things I've tried:
UPDATE t SET c=LEFT(c, 32); did not seem to do anything at all.
Using ALTER IGNORE TABLE gives me a syntax error.
To get around the #1265 - Data truncated for column ... error you must remove the STRICT_TRANS_TABLES flag from the global sql_mode variable.
The query SHOW VARIABLES LIKE 'sql_mode'; gave me:
STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
So I ran this query:
SET GLOBAL sql_mode = 'NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
For safety, I will re-enable strict mode after I'm done truncating columns.

MySQL varchar to number

I am trying a simple conversion - a mysql varchar column which contains longitude values (eg "-1.234" to -1.234) to enhance optimisation.
I have read and read on this and nothing works, last tried was:
UPDATE latlng_data SET lng_copy = CAST(lng AS DECIMAL(6,4));
met with:
Error Code: 1366. Incorrect decimal value: '' for column '' at row -1
Target column, created to recover from errors is:
FLOAT(6,4)
and null allowed.
Why is mysql error messages so useless.
Following 'dognose' advice (below) I have used:
UPDATE latlng_data SET lng='999.9999' where lng='';-- to give invalid lng in this case
then increase the copy data field (with the aim to rename it orig) and then:
UPDATE latlng_data SET lng_copy = CAST(lng AS DECIMAL(7,4));
this appears to be required in mysql cmd as Workbench timesout but using:
show full processlist;
still shows it as running - so here the best monitor is cmd.
I think the easiest way to convert numbers in MySQL is to use silent conversion. That is, use the string in an arithmetic operation and any conversion errors are ignored. A string with no numbers is interpreted as 0:
UPDATE latlng_data
SET lng_copy = lng + 0.0;
Here is some relevant documentation.
EDIT:
If you are concerned about matching only correct values, then check the format of the string
WHERE lng rlike '[0-9]+[.]?[0-9]*'
Checked this with:
SELECT * FROM t31data_happyenergy.latlng_data where lng_copy <> CAST(lng AS DECIMAL(7,4));
which now returns no results and can be better optimised as all are numerical, with bad data fully valued for a longitude.
I also recommend using a mysql command window as most apps timeout when extensive queries are used with this large data.
So basically the process went [ALWAYS CHECK BETWEEN EACH QUERY AS I GOT LAZY AND HAD TO START AGAIN AS ONE QUERY WAS WRONG):
-- convert all mostly read only tables to myisam:
-- dropped old lat and lng after checking same data by
SELECT count(*) FROM latlng_postcode where CAST(lat AS DECIMAL(7,4))!=latcopy;
SELECT count(*) FROM latlng_postcode where CAST(lng AS DECIMAL(7,4))!=lngcopy;
ALTER TABLE `latlng_postcode`
CHANGE COLUMN `latcopy` `lat` FLOAT(7,4) NULL DEFAULT NULL,
CHANGE COLUMN `lngcopy` `lng` FLOAT(7,4) NULL DEFAULT NULL;
-- then index (are these the best settings ??
ALTER TABLE `latlng_postcode`
DROP INDEX `pcode` ,
ADD INDEX `pcode` USING BTREE (`postcode`(5) ASC),
ADD INDEX `lat` USING BTREE (`lat`(4) ASC),
ADD INDEX `lng` USING BTREE (`lng`(4) ASC);

Inserting datetime value into sql server table column

I'm attempting to insert a datetime('2013-08-30 19:05:00') value into a SQL server database table column(smalldatetime) and the value stays "NULL" after the insert.
I'm doing this to 6 other columns that are the exact same type. What is this only occuring on one column? I've triple checked that the names of the columns are correct. Any ideas?
Assuming the situation is as you describe
CREATE TABLE T
(
S SMALLDATETIME NULL
)
INSERT INTO T
VALUES('2013-08-30 19:05:00')
SELECT *
FROM T /*Returns NULL*/
There are only two ways I can think of that this can happen.
1) That is an ambiguous datetime format. Under the wrong session options this won't cast correctly and if you have some additional options OFF it will return NULL rather than raise an error (e.g.)
SET LANGUAGE Italian;
SET ansi_warnings OFF;
SET arithabort OFF;
INSERT INTO T
VALUES('2013-08-30 19:05:00')
SELECT *
FROM T /*NULL inserted*/
2) You may have missed the column out in an INSTEAD OF trigger, or have an AFTER trigger that actually sets the value back to NULL.

Using variable as integer for AUTO_INCREMENT

I'm rather new to fiddling around in SQL and MySQL, although I stumbled upon this problem. I'm trying to get a number of how many rows are there in one table and set this number onto anothers AUTO_INCREMENT value. The problem is, MySQL workbench triggers a syntax error when I try to assign value via a variable. I tried to convert the query to unsigned integer, although not sure if it did work. Query for row amount returns the required number. What am I doing wrong?
SET #size = CONVERT((SELECT TABLE_ROWS FROM information_schema.tables WHERE table_name='Persons' and table_schema = 'Movies2'), unsigned);
ALTER TABLE Movies2.Actors AUTO_INCREMENT=#size;
The following should work:
ALTER TABLE Movies2.Actors AUTO_INCREMENT = (SELECT COUNT(*) FROM Movies2.Persons);