MySQL Results pivot table - of a sort - mysql

I have a table as defined below:
CREATE TABLE `z_data` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`subscriberid` INT(11) NOT NULL DEFAULT '0',
`Email Address` VARCHAR(255) NOT NULL DEFAULT '',
`Title` VARCHAR(255) NOT NULL DEFAULT '',
`First Name` VARCHAR(255) NOT NULL DEFAULT '',
`Last Name` VARCHAR(255) NOT NULL DEFAULT '',
`Postal Code` VARCHAR(255) NOT NULL DEFAULT '',
`banned` INT(11) NOT NULL DEFAULT '0',
`bounced` INT(1) NOT NULL DEFAULT '0',
`unsub` INT(1) NOT NULL DEFAULT '0',
`duplicate` INT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_subscriberid` (`subscriberid`),
KEY `idx_banned` (`banned`),
KEY `idx_bounced` (`bounced`),
KEY `idx_unsub` (`unsub`),
KEY `idx_duplicate` (`duplicate`),
KEY `idx_email` (`Email Address`),
FULLTEXT KEY `idx_emailaddress` (`Email Address`)
) ENGINE=MYISAM AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
This table is populated from a CSV file and a query updates the subscriberid column with a number if the emailaddress is allready present in the main database with a query like:
UPDATE `z_data` AS z
LEFT JOIN main_subscribers AS b ON (z.`Email Address`=b.emailaddress && b.listid=1 && b.unsubscribed!=0)
SET z.subscriberid = b.subscriberid
WHERE b.subscriberid IS NOT NULL;";
Now, my question. I need to select the subscriberids of all of the records in z_data in rows of ten fields, this can be comma seperated lists.
my result could be similar to:
1293572,1293573,1293574,1293575,1099590,1174275,1293576,1293577,1293578,1293579,
673070,813617,1293580,1293581,1293582,1131221,1293583,1182045,419085,1293584,
1050278,1293585,1064945,638483,737691,1293586,1293587,799800,1110596,1293588,
1293589,1293590,1293591,421394,1293592,1293593,1293594,1293595,1293596,851491,
1293597,1293598,1293599,628250,1293600,1293601,1293602,535366,1293603,256590,
1293604,1293605,736956,1293606,1209511,673075,1293607,1293608,1293609,754357,
The reason for this is so that I can store these values in a TEXT field for later use in a IN clause and yet have a reasonably human readable script.
I have managed to get the first row thus:
SELECT GROUP_CONCAT(a.subscriberid) AS 'IDs' FROM (
SELECT subscriberid FROM
`z_data`
WHERE subscriberid!=0
LIMIT 1,10
) AS a
but do not know how to 'walk' though the rest of the table when the number of rows with subscriberids is unknown.
Any suggestions would be gratefully received.

Related

MariaDB - CONNECT ENGINE - ORDER BY error

I'm trying to get Asterisk CDR records from MySQL table (5.5.45) by CONNECT engine on other server running MariaDB (10.0.29).
I can create the connection between table easily:
CREATE TABLE `calls` engine=CONNECT table_type=MYSQL
CONNECTION='mysql://user#IP/asteriskcdrdb/calls';
When I run simple SELECT * FROM calls, everything works good, when I add some WHERE conditions, still everything okay.
But the problem start when I add ORDER BY column parameter, then I got this error from MariaDB:
#1032 - Can't find record in 'calls'
I checked MySQL log, MariaDB log - there are no errors at all.
Did I miss something?
Thank you!
Update: The whole query is simple:
SELECT * FROM `calls` ORDER BY `calldate`
The table structure:
CREATE TABLE `calls` (
`calldate` datetime NOT NULL default '0000-00-00 00:00:00',
`clid` varchar(80) NOT NULL default '',
`src` varchar(80) NOT NULL default '',
`dst` varchar(80) NOT NULL default '',
`dcontext` varchar(80) NOT NULL default '',
`channel` varchar(80) NOT NULL default '',
`dstchannel` varchar(80) NOT NULL default '',
`lastapp` varchar(80) NOT NULL default '',
`lastdata` varchar(80) NOT NULL default '',
`duration` int(11) NOT NULL default '0',
`billsec` int(11) NOT NULL default '0',
`disposition` varchar(45) NOT NULL default '',
`amaflags` int(11) NOT NULL default '0',
`accountcode` varchar(20) NOT NULL default '',
`uniqueid` varchar(32) NOT NULL default '',
`userfield` varchar(255) NOT NULL default '',
`recordingfile` varchar(255) NOT NULL default '',
`cnum` varchar(40) NOT NULL default '',
`cnam` varchar(40) NOT NULL default '',
`outbound_cnum` varchar(40) NOT NULL default '',
`outbound_cnam` varchar(40) NOT NULL default '',
`dst_cnam` varchar(40) NOT NULL default '',
`call_charge` float NOT NULL default '0',
`from_did` varchar(30) NOT NULL,
`did` varchar(50) NOT NULL default '',
`user_id` int(8) unsigned default NULL,
`client_id` int(8) unsigned default NULL,
KEY `IDX_UNIQUEID` (`uniqueid`),
KEY `src` (`src`),
KEY `dst` (`dst`),
KEY `calldate` (`calldate`),
KEY `uniqueid` (`uniqueid`),
KEY `userfield` (`userfield`),
KEY `from_did` (`from_did`),
KEY `user_id` (`user_id`),
KEY `client_id` (`client_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Update #2: Update the table names, to don't confuse, but it's not the issue. The CONNECTION table is created okay.
Query works:
SELECT * FROM `calls`
Query works:
SELECT * FROM `calls` WHERE `user_id`=X
Query return error:
SELECT * FROM `calls` ORDER BY `calldate`
Update #3: The MySQL was updated to veriosn 5.5.45, the type was changed to InnoDB and the charset was converted to UTF8. But no success.
PROBLEM SOLVED
Well, it's MariaDB bug, when I changed to FederatedX engine (which is basically little bit limited version of CONNECT), everything works as expected.
In your query you do
SELECT * FROM calls
but in your table structure you have
CREATE TABLE cdr
and both have calldate column. Check if you querying the right table.

MySQL use separate indices for JOIN and GROUP BY

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

mysql 4.1.22 select command returns no rows when using distinct with order by

I have 2 tables: glgroup and glref
CREATE TABLE `glgroup` (
`GLREFID` varchar(2) NOT NULL default '',
`GLREFNO` varchar(20) NOT NULL default '',
PRIMARY KEY (`GLREFID`,`GLREFNO`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `glref` (
`GLREFNO` varchar(20) NOT NULL default '',
`GLDESC` varchar(255) NOT NULL default '',
`GLCUR` varchar(20) NOT NULL default '',
`GLADDFIELD` varchar(20) default NULL,
`GLADDFIELD2` varchar(20) default NULL,
`GLADDFIELD3` varchar(20) default NULL,
`GLADDFIELDDESC` tinytext,
PRIMARY KEY (`GLREFNO`,`GLCUR`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
i have this query:
SELECT DISTINCT
GLREF.GLREFNO,
GLREF.GLDESC
FROM GLGROUP,
GLREF
WHERE GLGROUP.GLREFID = '07'
AND GLGROUP.GLREFNO = GLREF.GLREFNO
ORDER BY GLREF.GLREFNO;
Sometimes (quite often), this query returns no rows. If I remove order by clause, it returns 76 rows (when it runs correctly, it returns 76 rows too), if I remove both distinct and order by clause, it returns 697 rows.
the problem is that, this query is in app code and I cannot modify it. What can I do?

Mysql query with special characters?

I (newbie) have hard time to understand this query:
$result = mysql_query("
SELECT q.*, IF(v.id,1,0) AS voted
FROM quotes AS q
LEFT JOIN quotes_votes AS v
ON q.id = v.qid
AND v.ip =".$ip."
AND v.date_submit = '".$today."'
");
can anybody provide more info on what these short symbols like 'q.*' with the if statement and v.id,1,0. Any sources to read more about this?
Thank you very much.
this is how the tables looks like:
CREATE TABLE `quotes` (
`id` smallint(5) unsigned NOT NULL auto_increment,
`txt` varchar(255) collate utf8_unicode_ci NOT NULL default '',
`author` varchar(32) collate utf8_unicode_ci NOT NULL default '',
`bgc` varchar(32) collate utf8_unicode_ci NOT NULL default '',
`votes` mediumint(9) unsigned NOT NULL default '0',
`vsum` int(11) unsigned NOT NULL default '0',
`rating` double NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `rating` (`rating`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16 ;
CREATE TABLE `quotes_votes` (
`id` mediumint(9) unsigned NOT NULL auto_increment,
`qid` smallint(6) unsigned NOT NULL default '0',
`ip` int(10) NOT NULL default '0',
`vote` tinyint(1) NOT NULL default '0',
`date_submit` date NOT NULL default '0000-00-00',
`dt_submit` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `qid` (`qid`,`ip`,`date_submit`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Regarding select q.*, it just means getting all fields from the table alias q, which happens to be table quotes. It is like select * but just for one table.
Regarding IF(v.id,1,0), that is really a MySQLism. The IF statement evaluates an expression given in the first argument and, if it is true, returns the second argument. Otherwise it returns the third argument. So you know that a 1 or a 0 will come out of the IF. You might now be wondering how can v.id be evaluated to return a logical value and the reason behind it is that MySQL treats booleans as if they were TINYINT(1) in which 0 is considered as false and non-zero values are considered as true.
So that would be rephrased into IF(v.id != 0, 1, 0) which might be easier to read. Given the fact that v.id can not be null then you could rewrite that this way IF(v.id = 0, 0, 1). Anyway, you could take a step further and just replace it with v.id != 0 :)

Find row that have a duplicate field, the filed type is blob

I have a table with many many duplicated row, I cannot create a unique value for the blob field, because is too large.
How can I find and delete the duplicate rows where the blob field (answer) is duplicated?
This is the table structure :
CREATE TABLE `answers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_question` int(11) NOT NULL,
`id_user` int(11) NOT NULL,
`answer` blob NOT NULL,
`language` varchar(2) NOT NULL,
`datetime` datetime NOT NULL,
`enabled` int(11) NOT NULL DEFAULT '0',
`deleted` int(11) NOT NULL DEFAULT '0',
`spam` int(11) NOT NULL DEFAULT '0',
`correct` int(11) NOT NULL DEFAULT '0',
`notification_send` int(11) NOT NULL DEFAULT '0',
`correct_notification` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `id_question` (`id_question`),
KEY `id_user` (`id_user`),
KEY `enabled` (`enabled`)
) ENGINE=InnoDB AUTO_INCREMENT=1488 DEFAULT CHARSET=utf8mb4
probable you can use prefix of the column by substr() or left() and compare. How much size you want to take that depends on your data distribution or prefix uniqueness of the column data.
for uniqueness check you can fire the below query if the
select count(distinct left(answer, 128))/count(*), count(distinct left(answer, 256))/count(*) from answers.
This will provide you selectivity or data distribution in your column. suppose 128 gives you answer as 1 i.e. all unique if you take first 128 bytes then choose that amount of data from each row and work. Hope it helps.