SQL select for serial column - mysql

Assume I have a data with columns :
aa1, aa2, aa3, aa4, aa5, aa6
and so on.
I 'm looking for a select query where I can just mention something like :
select aa[1 to n] from table...
Is there any way to do it directly ?
Thanks

In MariaDB there is a system settings in database information_schema where are defined all schemas, tables, columns, etc.
Using this you can list all details about the table and use it to compose the "dynamic" query as you need.
Example of table definition:
CREATE TABLE `tablename` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`aa1` INT(11) NULL DEFAULT NULL,
`aa2` INT(11) NULL DEFAULT NULL,
`aa3` INT(11) NULL DEFAULT NULL,
`aa4` INT(11) NULL DEFAULT NULL,
`aa5` INT(11) NULL DEFAULT NULL,
`aa6` INT(11) NULL DEFAULT NULL,
`aa7` INT(11) NULL DEFAULT NULL,
`aa8` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_bin'
ENGINE=InnoDB
AUTO_INCREMENT=3
;
The query to information_schema to list the tables:
SELECT GROUP_CONCAT(COLUMN_NAME) FROM information_schema.`COLUMNS`
WHERE TABLE_SCHEMA = 'stackoverflow'
AND TABLE_NAME = 'tablename'
AND COLUMN_NAME LIKE 'aa%'
And the result:
aa1,aa2,aa3,aa4,aa5,aa6,aa7,aa8
So you can then built your query as needed.
Edit:
In SQL documentation is said: "Do not use INFORMATION_SCHEMA views to determine the schema of an object. The only reliable way to find the schema of a object is to query the sys.objects catalog view."

Related

How to store translates in MySQL to use join?

I have a table that contains all translations of words:
CREATE TABLE `localtexts` (
`Id` int(11) NOT NULL,
`Lang` char(2) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'pe',
`Text` varchar(300) DEFAULT NULL,
`ShortText` varchar(100) NOT NULL,
`DbVersion` timestamp NOT NULL DEFAULT current_timestamp(),
`Status` int(11) NOT NULL DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
As example there is a table that refers to localtexts:
CREATE TABLE `composes` (
`Status` int(11) NOT NULL DEFAULT 1,
`Id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The table above has foreign key Id to localtexts.Id. And when I need to get word on English I do:
SELECT localtexts.text,
composes.status
FROM composes
LEFT JOIN localtexts ON composes.Id = localtexts.Id
WHERE localtexts.Lang = 'en'.
I'm concerned in performance this decision when there are a lot of tables for join with localtexts.
You might find that adding the following index to the localtexts table would speed up the query:
CREATE INDEX idx ON localtexts (Lang, id, text);
This index covers the WHERE clause, join, and SELECT.

Mysql Query SELECT auto_increment given null

query create table :
CREATE TABLE `tb_master_status` (
`tbms_id` bigint NOT NULL AUTO_INCREMENT,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`tbms_desc` varchar(255) DEFAULT NULL,
`tbms_id_parent` bigint DEFAULT NULL,
PRIMARY KEY (`tbms_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
after that I added some data to the table ..
but when I run this query, it returns NULL value :
SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = "tb_master_status"
Why did it happen ?
you can try the permission for the user and following method
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = "yourDatabaseName"
AND TABLE_NAME = "yourTableName"

How to generate the table schema from INFORMATION_SCHEMA in MySQL?

I trying to generate table structure using INFORMATION_SCHEMA in MySQL.
I need the same output as
SHOW CREATE TABLE Mytablename;
My intention is to generation create table script for list of tables in mysql.
please help. I need to take table scripts for 100 tables. like below
CREATE TABLE `customer_list` (
`ID` smallint(5) unsigned NOT NULL DEFAULT '0',
`name` varchar(91) DEFAULT NULL,
`address` varchar(50) NOT NULL,
`zip_code` varchar(10) DEFAULT NULL,
`phone` varchar(20) NOT NULL,
`city` varchar(50) NOT NULL,
`country` varchar(50) NOT NULL,
`notes` varchar(6) NOT NULL DEFAULT '',
`SID` tinyint(3) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
SHOW CREATE TABLE your_table_name;
The SQL query to get the table structure from the INFORMATION SCHEMA is as follows, where the database name is "dbname" and the table name is "Mytablename":
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dbname'
AND TABLE_NAME = 'Mytablename';

How to update / insert data from table belong to database "A" to table belong to a database "B"?

How to update / insert data from table belong to database "A" to table belong to a database "B" ?
For example, I have a table in the name of ips as below belong to database "A":
CREATE TABLE `ips` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`begin_ip_num` int(11) unsigned DEFAULT NULL,
`end_ip_num` int(11) unsigned DEFAULT NULL,
`iso` varchar(3) DEFAULT NULL,
`country` varchar(150) DEFAULT NULL
) ENGINE=InnoDB
Let's assume I have a second table country belongs to database "B":
CREATE TABLE `country` (
`countryid` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`ordering` smallint(5) unsigned NOT NULL DEFAULT '0',
`iso` char(2) NOT NULL,
PRIMARY KEY (`countryid`)
) ENGINE=InnoDB
note :the two database are in the same server
You have to prefix the table names by the DB/schema name. Something like that:
INSERT INTO `database B`.`country` (columns)
SELECT columns FROM `database A`.`ips`;
Of course, you have to replace columns by the required column names and/or expression corresponding to your needs.
In SQLServer it goes like;
insert into x select * from otherdatabase.owner.table
Which can be expanded to select columns etc..
In Oracle you might need a database link bvetween them. THat was a long time ago for me ;-)

Avoid UNION for two almost identical tables in MySQL

I'm not very good at MySQL and i'm going to write a query to count messages sent by an user, based on its type and is_auto field.
Messages can be of type "small text message" or "newsletter". I created two entities with a few fields that differs between them. The important one is messages_count that is absent in table newsletter and it's used in the query:
CREATE TABLE IF NOT EXISTS `small_text_message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`messages_count` int(11) NOT NULL,
`username` varchar(255) NOT NULL,
`method` varchar(255) NOT NULL,
`content` longtext,
`sent_at` datetime DEFAULT NULL,
`status` varchar(255) NOT NULL,
`recipients_count` int(11) NOT NULL,
`customers_count` int(11) NOT NULL,
`sheduled_at` datetime DEFAULT NULL,
`sheduled_for` datetime DEFAULT NULL,
`is_auto` tinyint(1) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
And:
CREATE TABLE `newsletter` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`subject` varchar(78) DEFAULT NULL,
`content` longtext,
`sent_at` datetime DEFAULT NULL,
`status` varchar(255) NOT NULL,
`recipients_count` int(11) NOT NULL,
`customers_count` int(11) NOT NULL,
`sheduled_at` datetime DEFAULT NULL,
`sheduled_for` datetime DEFAULT NULL,
`is_auto` tinyint(1) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
I ended up with a UNION query. Can this query be shortened or optimized since the only difference is messages_count that should be always 1 for newsletter?
SELECT
CONCAT('sms_', IF(is_auto = 0, 'user' , 'auto')) AS subtype,
SUM(messages_count * (customers_count + recipients_count)) AS count
FROM small_text_message WHERE status <> 'pending' AND user_id = 1
GROUP BY is_auto
UNION
SELECT
CONCAT('newsletter_', IF(is_auto = 0, 'user' , 'auto')) AS subtype,
SUM(customers_count + recipients_count) AS count
FROM newsletter WHERE status <> 'pending' AND user_id = 1
GROUP BY is_auto
I don't see any easy way to avoid a UNION (or UNION ALL) operation, that will return the specified result set.
I would recommend you use a UNION ALL operator in place of the UNION operator. Then the execution plan will not include the step that eliminates duplicate rows. (You already have GROUP BY operations on each query, and there is no way that those two queries can produce an identical row.)
Otherwise, your query looks fine just as it is written.
(It's always a good thing to consider the question, might there be a better way? To get the result set you are asking for, from the schema you have, your query looks about as good as it's going to get.)
If you are looking for more general DB advice, I recommend restructuring the tables to factor the common elements into one table, perhaps called outbound_communication or something, with all of your common fields, then perhaps have "sub tables" for the specific types to host the fields which are unique to that type. It does mean a simple JOIN is necessary to select all of the fields you want, but the again, it's normalized and actually makes situations like this one easier (one table holds all of the entities of interest). Additionally, you have the option of writing that JOIN just once as a "view", and then your existing code would not even need to change to see the two tables as if they never changed.
CREATE TABLE IF NOT EXISTS `outbound_communicaton` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`content` longtext,
`sent_at` datetime DEFAULT NULL,
`status` varchar(255) NOT NULL,
`recipients_count` int(11) NOT NULL,
`customers_count` int(11) NOT NULL,
`sheduled_at` datetime DEFAULT NULL,
`sheduled_for` datetime DEFAULT NULL,
`is_auto` tinyint(1) NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `small_text_message` (
`oubound_communication_id` int(11) NOT NULL,
`messages_count` int(11) NOT NULL,
`username` varchar(255) NOT NULL,
`method` varchar(255) NOT NULL,
PRIMARY KEY (`outbound_communication_id`),
FOREIGN KEY (outbound_communication_id)
REFERENCES outbound_communicaton(id)
) ENGINE=InnoDB;
CREATE TABLE `newsletter` (
`oubound_communication_id` int(11) NOT NULL,
`subject` varchar(78) DEFAULT NULL,
PRIMARY KEY (`outbound_communication_id`),
FOREIGN KEY (outbound_communication_id)
REFERENCES outbound_communicaton(id)
) ENGINE=InnoDB;
Then selecting a text msg is like this:
SELECT *
FROM outbound_communication AS parent
JOIN small_text_message
ON parent.id = small_text_message.outbound_communication_id
WHERE parent.id = 1234;
The nature of the query is inherently the union of the data from the small text message and the newsletter tables, so the UNION query is the only realistic formulation. There's no join of relevance between the two tables, for example.
So, I think you're very much on the right lines with your query.
Why are you worried about a UNION?