As sometimes happens, a block of code fails and no matter how hard you try, you can't figure out where it is. In these cases a second pair of eyes sometimes sees what the brain doesn't register. I think this is one of those cases. It's almost certainly my fault and I did something wrong but I honestly can't figure out where.
This is a SELECT I wrote
SELECT
`a.dev_act_id`,
`a.dev_act_code`,
`a.dev_act_desc`,
`a.dev_act_type`,
`a.lang_code`,
`pa.dev_plan_act_id`,
`pa.action_status`,
`pa.action_expiration`,
`cb.competence_id`,
`cb.credits` AS `avail_credits`,
`w.credits` AS `settled_credits`
FROM
`pbq_idp_plan_actions` AS pa
INNER JOIN `pbq_idp_dev_actions` AS a ON `pa.dev_act_id` = `a.dev_act_id`
INNER JOIN `pbq_idp_credit_bags` AS cb ON `pa.dev_plan_act_id` = `cb.dev_plan_act_id`
INNER JOIN `pbq_idp_wallets` AS w ON `a.dev_act_id` = `w.dev_act_id`
WHERE
`pa.dev_plan_id` = 0
ORDER BY
`cb.competence_id`
The structure of the pbq_idp_dev_actions table whose alias is 'a', is as follows
CREATE TABLE `pbq_idp_dev_actions` (
`dev_act_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`wallet_id` bigint(20) unsigned NOT NULL,
`dev_act_code` text COLLATE utf8mb4_unicode_520_ci NOT NULL,
`dev_act_desc` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL,
`dev_act_type` tinyint(1) unsigned NOT NULL DEFAULT '0',
`lang_code` varchar(7) COLLATE utf8mb4_unicode_520_ci NOT NULL,
PRIMARY KEY (`dev_act_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci
It would seem that everything is fine, but I get the following error and I don't understand why. The alias is correct, the field exists, yet the system can't find it.
WordPress database error: [Unknown column 'a.dev_act_id' in 'field list']
By request, here are the other three tables:
CREATE TABLE `pbq_idp_plan_actions` (
`dev_plan_act_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`dev_act_id` bigint(20) unsigned NOT NULL,
`dev_plan_id` bigint(20) unsigned NOT NULL,
`action_status` tinyint(2) unsigned NOT NULL DEFAULT '0',
`not_earlier` datetime DEFAULT NULL,
`deadline` datetime DEFAULT NULL,
PRIMARY KEY (`dev_plan_act_id`),
KEY `dev_act_id` (`dev_act_id`,`dev_plan_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci
CREATE TABLE `pbq_idp_credit_bags` (
`credit_bag_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`dev_plan_act_id` bigint(20) unsigned NOT NULL,
`competence_id` varchar(4) COLLATE utf8mb4_unicode_520_ci NOT NULL,
`credits` tinyint(3) NOT NULL DEFAULT '0',
PRIMARY KEY (`credit_bag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci
CREATE TABLE `pbq_idp_wallets` (
`wallet_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`dev_act_id` bigint(20) unsigned NOT NULL,
`competence_id` varchar(4) COLLATE utf8mb4_unicode_520_ci NOT NULL,
`credits` tinyint(3) NOT NULL DEFAULT '0',
PRIMARY KEY (`wallet_id`),
KEY `dev_act_id` (`dev_act_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci
The problem is in the wrong usage of backticks as can be seen in this example and the column action_expiration doesn't exist on pbq_idp_plan_actions table.
Backticks are used in MySQL to select Schema Object Names. Do not put the alias name inside backticks.
Not valid
`a.dev_act_id`
Valid
a.`dev_act_id`.
In your case backticks are exces
Related
This question is completely different from similar ones. There is no foreign key in the SQL query. This is a silly error I see when I import the SQL file on remote server. This is the SQL code
CREATE TABLE `locations` (
`id` int(10) UNSIGNED NOT NULL,
`title` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
As you see there is no foreign key, But when I run the following code, it is ok
CREATE TABLE `locations` (
`id` int(10) UNSIGNED NOT NULL,
`title` varchar(191) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ;
If I rename it to something else it is OK too.
CREATE TABLE `locationssss` (
`id` int(10) UNSIGNED NOT NULL,
`title` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
what is wrong?
Just for future references:
Do you have more tables within your database? If so, is there a table that does contain a foreign key connected with the locations table?
I am trying to execute following query
SELECT
a.sessionID AS `sessionID`,
firstSeen, birthday, gender,
isAnonymous, LanguageCode
FROM transactions AS trx
INNER JOIN actions AS a ON a.sessionID = trx.SessionID
WHERE a.ActionType = 'PURCHASE'
GROUP BY trx.TransactionNumber
Explain provides the following output
1 SIMPLE trx ALL TransactionNumber,SessionID NULL NULL NULL 225036 Using temporary; Using filesort
1 SIMPLE a ref sessionID sessionID 98 infinitiExport.trx.SessionID 1 Using index
The problem is that I am trying to use one field for join and different field for GROUP BY.
How can I tell MySQL to use different indices for same table?
CREATE TABLE `transactions` (
`SessionID` varchar(32) NOT NULL DEFAULT '',
`date` datetime DEFAULT NULL,
`TransactionNumber` varchar(32) NOT NULL DEFAULT '',
`CustomerECommerceTrackID` int(11) DEFAULT NULL,
`SKU` varchar(45) DEFAULT NULL,
`AmountPaid` double DEFAULT NULL,
`Currency` varchar(10) DEFAULT NULL,
`Quantity` int(11) DEFAULT NULL,
`Name` tinytext NOT NULL,
`Category` varchar(45) NOT NULL DEFAULT '',
`customerInfoXML` text,
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
KEY `TransactionNumber` (`TransactionNumber`),
KEY `SessionID` (`SessionID`)
) ENGINE=InnoDB AUTO_INCREMENT=212007 DEFAULT CHARSET=utf8;
CREATE TABLE `actions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sessionActionDate` datetime DEFAULT NULL,
`actionURL` varchar(255) DEFAULT NULL,
`sessionID` varchar(32) NOT NULL DEFAULT '',
`ActionType` varchar(64) DEFAULT NULL,
`CustomerID` int(11) DEFAULT NULL,
`IPAddressID` int(11) DEFAULT NULL,
`CustomerDeviceID` int(11) DEFAULT NULL,
`customerInfoXML` text,
PRIMARY KEY (`id`),
KEY `ActionType` (`ActionType`),
KEY `CustomerDeviceID` (`CustomerDeviceID`),
KEY `sessionID` (`sessionID`)
) ENGINE=InnoDB AUTO_INCREMENT=15042833 DEFAULT CHARSET=utf8;
Thanks
EDIT 1: My indexes were broken, I had to add (SessionID, TransactionNumber) index to transactions table, however now, when I try to include trx.customerInfoXML table mysql stops using index
EDIT 2 Another answer does not really solved my problem because it's not standard sql syntax and generally not a good idea to force indices.
For ORM users such syntax is a unattainable luxury.
EDIT 3 I updated my indices and it solved the problem, see EDIT 1
I like to append a table to add column but without using alert table command
e.g.
This is the table which is missing some columns.
CREATE TABLE IF NOT EXISTS `admin` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(20) NOT NULL,
`passwd` varchar(40) NOT NULL,
`isActive` tinyint(1) NOT NULL default '1',
`lastVisit` datetime NOT NULL default '0000-00-00 00:00:00',
`modifyAt` datetime NOT NULL,
`createdAt` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
So if i run this query then it should automatically add missing columns into my tables
CREATE TABLE IF NOT EXISTS `admin` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(20) NOT NULL,
`passwd` varchar(40) NOT NULL,
`name` varchar(100) NOT NULL,
`originalUser` tinyint(1) NOT NULL default '0',
`isActive` tinyint(1) NOT NULL default '1',
`lastVisit` datetime NOT NULL default '0000-00-00 00:00:00',
`modifyAt` datetime NOT NULL,
`createdAt` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Can this be possible to do without using alert table command ?
I understand your question as you want to add some columns to your table. Please be informed that the term row is usually related to the actual data in your table, not the columns itself. If my assumption is wrong, please clarify your question.
You cannot use CREATE TABLE for altering a table. It is there to create table,
and if it cannot create it, it will in most cases throw an error like you described. Another command exists for that reason: ALTER TABLE.
You might do it something like this.
(1) Create your table with your CREATE TABLE syntax above:
CREATE TABLE IF NOT EXISTS `admin` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(20) NOT NULL,
`passwd` varchar(40) NOT NULL,
`isActive` tinyint(1) NOT NULL default '1',
`lastVisit` datetime NOT NULL default '0000-00-00 00:00:00',
`modifyAt` datetime NOT NULL,
`createdAt` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
(2) Use ALTER TABLE like this to make the modifications I think you want to have in your second statement (two more columns):
ALTER TABLE
ADD COLUMN `name` varchar(100) NOT NULL AFTER `passwd`,
ADD COLUMN `originalUser` tinyint(1) NOT NULL default '0' AFTER `name`;
Not related to your question, but I'd avoid column names like name, because if you don't escape them properly it'll throw you other errors (see reserved words).
Does anybody know what is wrong in this MYSQL 5.0 syntax?
CREATE TABLE IF NOT EXISTS target (
_id int(11) NOT NULL AUTO_INCREMENT,
time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
map_id int(11) DEFAULT NULL,
left int(11) DEFAULT NULL,
top int(11) DEFAULT NULL,
status tinyint(1) NOT NULL,
temperature int(11) DEFAULT NULL,
humidity float DEFAULT NULL,
lum int(11) DEFAULT NULL,
PRIMARY KEY (_id),
FOREIGN KEY (map_id) REFERENCES map(id) ON DELETE CASCADE
)
I'll show you the error:
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 'left INTEGER DEFAULT NULL,
top INTEGER DEFAULT NULL,
status tinyint(1) NOT' at line 5
Because left is a MySQL 5.0 reserved word. Also, even though you can escape the field name, it's never a great idea to use reserved words in a table definition.
you must write it like this:
CREATE TABLE IF NOT EXISTS target (
_id int(11) NOT NULL AUTO_INCREMENT,
time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
map_id int(11) DEFAULT NULL,
`left` int(11) DEFAULT NULL,
top int(11) DEFAULT NULL,
status tinyint(1) NOT NULL,
temperature int(11) DEFAULT NULL,
humidity float DEFAULT NULL,
lum int(11) DEFAULT NULL,
PRIMARY KEY (_id),
FOREIGN KEY (map_id) REFERENCES map(id) ON DELETE CASCADE
)
look at the `` (backticks) characters in left row !
You're using reserved words as field names. You can do that, but then you have to properly escape them, like this:
CREATE TABLE IF NOT EXISTS target (
`_id` int(11) NOT NULL AUTO_INCREMENT,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`map_id` int(11) DEFAULT NULL,
`left` int(11) DEFAULT NULL,
`top` int(11) DEFAULT NULL,
`status` tinyint(1) NOT NULL,
`temperature` int(11) DEFAULT NULL,
`humidity` decimal(13,2) DEFAULT NULL,
`lum` int(11) DEFAULT NULL,
PRIMARY KEY (_id),
FOREIGN KEY (map_id) REFERENCES map(id) ON DELETE CASCADE
)
My advise would be to avoid reserved names.
Is it possible for mysqldump to dump one query per line?
For example, it currently dumps a CREATE TABLE expressions like so:
--
-- Table structure for table `post`
--
CREATE TABLE IF NOT EXISTS `post` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(160) NOT NULL,
`slug` varchar(255) NOT NULL,
`url` varchar(600) NOT NULL,
`domain` varchar(90) NOT NULL,
`author` int(11) NOT NULL,
`description` text,
`category` int(11) DEFAULT NULL,
`score` int(11) NOT NULL,
`ip` varchar(255) DEFAULT NULL,
`created` datetime NOT NULL,
`comment_count` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `uc_slug` (`slug`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`login` varchar(12) NOT NULL,
`password` varchar(45) NOT NULL,
`email` varchar(150) NOT NULL,
`about` varchar(300) DEFAULT NULL,
`last_visit` datetime DEFAULT NULL,
`ip` varchar(255) DEFAULT NULL,
`created` datetime NOT NULL,
`perm_mod` int(11) DEFAULT NULL,
`perm_admin` int(11) DEFAULT NULL,
`post_count` int(11) NOT NULL DEFAULT '0',
`comment_count` int(11) NOT NULL DEFAULT '0',
`vote_count` int(11) NOT NULL DEFAULT '0',
`voted_count` int(11) NOT NULL DEFAULT '0',
`forgot_key` varchar(150) DEFAULT NULL,
`cookie_key` varchar(40) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3;
Instead, I want it to dump like this:
--
-- Table structure for table `post`
--
CREATE TABLE IF NOT EXISTS `post` (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(160) NOT NULL,`slug` varchar(255) NOT NULL,`url` varchar(600) NOT NULL,`domain` varchar(90) NOT NULL,`author` int(11) NOT NULL,`description` text,`category` int(11) DEFAULT NULL,`score` int(11) NOT NULL,`ip` varchar(255) DEFAULT NULL,`created` datetime NOT NULL,`comment_count` int(11) NOT NULL DEFAULT '0',PRIMARY KEY (`id`),UNIQUE KEY `uc_slug` (`slug`) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`login` varchar(12) NOT NULL,`password` varchar(45) NOT NULL,`email` varchar(150) NOT NULL,`about` varchar(300) DEFAULT NULL,`last_visit` datetime DEFAULT NULL,`ip` varchar(255) DEFAULT NULL,`created` datetime NOT NULL,`perm_mod` int(11) DEFAULT NULL,`perm_admin` int(11) DEFAULT NULL,`post_count` int(11) NOT NULL DEFAULT '0',`comment_count` int(11) NOT NULL DEFAULT '0',`vote_count` int(11) NOT NULL DEFAULT '0',`voted_count` int(11) NOT NULL DEFAULT '0',`forgot_key` varchar(150) DEFAULT NULL,`cookie_key` varchar(40) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3;
I have been going through the args for mysqldump, and can't find anything that would do this
Indeed, there is no command-line switch to achieve this. Instead I recommend you to do the dump normally and then use a good text editor like Notepad++ to open dump file.
First select block to convert to single line, then select menu option of the folowing image.
This is the result (repeat for every block to convert to single line):
I had similar task - to format mysqldump output file to be mysql init_file option compatible. Here is the solution:
sed ':a;N;$!ba;s/\n/THISISUNIQUESTRING/g' | sed -e 's/;THISISUNIQUESTRING/;\n/g' | sed -e 's/THISISUNIQUESTRING//g'
This replaces all newline chars with a weird string that is not present in the file. Next sed replaces the combination of this string and semicolon with semicolon and newline char. This is needed because table data can contain string values that include ";", so straighforward removal of all newline chars and adding them after semicolons is not universal.
After that remaining weird strings are just removed from the text.
Btw, I was running mysqldump with --comments=false parameter, as comments are not allowed for "init_file" thing as well.
If you truly want individual queries the most pragmatic solution in my book would be to use the built-in functionality of mysqldump. The --skip-extended-insert flag is what you want, it is not clear in the documentation but it gives you the dump format you want.