MySQL set the result of a query = to a column binary - mysql

I want to create a new variable/column in my dataset that signifies the presence or lack there of a data mining query.
I thought it would be:
SELECT * INTO #variable1
FROM dataset
WHERE CONTENTS RLIKE '[[:<:]]foo[[:>:]]'
OR CONTENTS RLIKE '[[:<:]]example[[:>:]]'
However I get the error:
Operand should contain 1 column(s).
I think I somehow need to say SELECT as a binary (not as *), but not sure how to do this.

You need to do two things in order to accomplish this.
First, you must alter dataset to have a column for your result:
ALTER TABLE dataset ADD CONTENTS_FLAG tinyint(1) NOT NULL default 0.
Now, you need to update the new dataset column with the results of your query:
UPDATE dataset SET CONTENTS_FLAG = 1
WHERE CONTENTS RLIKE '[[:<:]]foo[[:>:]]'
OR CONTENTS RLIKE '[[:<:]]example[[:>:]]'

Related

MySQL - Copying partial data from one table to another

This may be a silly question, and I understand why I'm getting the result that I am, however, I thought mySQL acted differently and I can't finish the documentation to tell me otherwise.
I have 2 basic tables as follows:
CREATE TABLE test ( num INT, time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP );
CREATE TABLE test_to_copy ( num INT );
I then create a single entry into the test_to_copy table:
INSERT INTO test_to_copy VALUES ( 12 );
Now I try and copy the table test_to_copy to test like so:
INSERT INTO test SELECT * FROM test_to_copy;
The error that keeps getting thrown is
"Column count doesn't match value count at row 1".
I know that it is complaining that the number of columns in both tables does not match meaning it does not know what variable we are assigning our copy to, however, should it not be a case where the time is created automatically i.e. defaulted if nothing is inserted when we do the copy rather than throw the error?
Due to constraints, I can no longer have the time in both tables, and I must do a SELECT * on the test_to_copy table as there are over 50 columns, and i'm wondering is there an easy way around this?
This is another variation of a frequent question: "can I query *-except-for-one-column?"
No, there is no wildcard-with-exceptions syntax in SQL. The * wildcard means all columns. If you don't want all columns, you must name the columns explicitly.
If you have a variety of columns because this method may be used for more than one table, you can get the list of columns for any given table from INFORMATION_SCHEMA.COLUMNS and use that information to build a dynamic SQL query.
Here's a way you can produce the list of columns:
SELECT
GROUP_CONCAT(
CONCAT('`', column_name, '`')
) AS _cols
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='mydatabase' AND TABLE_NAME='mytable'
AND COLUMN_NAME NOT IN ('time'); -- or other columns to exclude
See also:
Select all columns except one in MySQL?
SQL exclude a column using SELECT * [except columnA] FROM tableA?
INSERT INTO test (num)
SELECT num
FROM test_to_copy

SQL coalesce(): what type does the combined column have?

Lets say I use coalesce() to combine two columns into one in select and subsequently a view constructed around such select.
Tables:
values_int
id INTEGER(11) PRIMARY KEY
value INTEGER(11)
values_varchar
id INTEGER(11) PRIMARY KEY
value VARCHAR(255)
vals
id INTEGER(11) PRIMARY KEY
value INTEGER(11) //foreign key to both values_int and values_varchar
The primary keys between values_int and values_varchar are unique and that allows me to do:
SELECT vals.id, coalesce(values_int.value, values_varchar.value) AS value
FROM vals
JOIN values_int ON values_int.id = vals.value
JOIN values_varchar ON values_varchar.id = vals.value
This produces nice assembled view with ID column and combined value column that contains actual values from two other tables combined into single column.
What type does this combined column have?
When turned into view and then queried with a WHERE clause using this combined "value" column, how is that actually handled type-wise? I.e. WHERE value > 10
Som rambling thoughts in the need (most likely wrong):
The reason I am asking this is that the alternative to this design have all three tables merged into one with INT values in one column and VARCHAR in the other. That would of course produce a lots of NULL values in both columns but saved me the JOINs. For some reason I do not like that solution because it would require additional type checking to choose the right column and deal with the NULL values but maybe this presented design would require the same too (if the resulting column is actually VARCHAR). I would hope that it actually passes the WHERE clause down the view to the source (so that the column does NOT have a type per se) but I am likely wrong about that.
You query should be explicit to be clear, In this case mysql is using varchar.
I would write this query like this to be clear
coalesce(values_int.value,cast(values_varchar.value as integer), 0)
or
coalesce(cast(values_int.value as varchar(20)),values_varchar.value,'0')
you should put in that last value unless you want the column to be null if both columns are null.
Returns the data type of expression with the highest data type precedence. If all expressions are nonnullable, the result is typed as nonnullable.
So in your case the type will be VARCHAR(255)
Lets say I use coalesce() to combine two columns into one
NO, that's not the use of COALESCE function. It's used for choosing a provided default value if the column value is null. So in your case, if values_int.value IS NULL then it will select the value in values_varchar.value
coalesce(values_int.value, values_varchar.value) AS value
If you want to combine the data then use concatenation operator (OR) CONCAT() function rather like
concat(values_int.value, values_varchar.value) AS value
Verify it yourself. An easy way to check in MySQL is to DESCRIBE a VIEW you create to capture your dynamic column:
mysql> CREATE VIEW v AS
-> SELECT vals.id, coalesce(values_int.value, values_varchar.value) AS value
-> FROM vals
-> JOIN values_int ON values_int.id = vals.value
-> JOIN values_varchar ON values_varchar.id = vals.value;
Query OK, 0 rows affected (0.01 sec)
Now DESCRIBE v will show you what's what. Note that under MySQL 5.1, I see the column as varbinary(255), but under 5.5 I see varchar(255).

increment a value when a row is selected SQL

Is there any way to essentially keep track of how many times a row has been pulled from a SQL table?
For example in my table I have a column count. Every time a SQL statement pulls a particular row (lets call it rowA), rowA's 'count' value increases 1.
Either in the settings of the table or in the statement would be fine, but i cant find anything like this.
I know that I could split it into two statements to achieve the same thing, but I would prefer to only send one.
The best way to do this is to restrict read-access of the table to a stored procedure.
This stored procedure would take various inputs (filter options) to determine which rows are returned.
Before the rows are returned, their counter field is incremented.
Note that the update and the select command share the same where clause.
create procedure Select_From_Table1
#pMyParameter varchar(20), -- sample filter parameter
as
-- First, update the counter, only on the fields that match our filter
update MyTable set Counter = Counter + 1
where
MyFilterField like CONCAT('%', #pMyParameter, '%') -- sample filter enforcement
-- Now, return those rows
select
*
from
MyTable
where
MyFilterField like CONCAT('%', #pMyParameter, '%') -- sample filter enforcement
A decent alternative would be to handle it on the application side in your data-access layer.

how to change a lot of records at once in phpmyadmin

I'd like to know how to update several records at once where a certain column type is selected.
I have found how to select records. I have found how to update records. But i don't know how to do it both together for it to work.
Selecting:
SELECT * FROM users WHERE 'type'='new'
Updating:
update table
set column = 937
So basically i want to change the info in the 'column' to 937 in the 'table' if another column 'type' is 'new'.
Thanks,
You can do this by simply adding a WHERE clause to your UPDATE statement:
UPDATE `users`
SET `myColumn` = 937
WHERE `type` = 'new'
Of course, change myColumn to match your column name
You can do this with a subquery :
update users
set column = 937
where id in (select id from users where type='new')
Just change the columns name if I got them wrong.
After researching for a while I found another solution to this problem. When referencing the same table or field name in a query, the name space in MySQL ends up with duplicates and fails. To overcome this use the "AS" syntax to name the duplicate items. Also, update queries often require a key field to be used as the parameter for the where clause, this is often your auto-incremented ID field. This example provides a solution for both of these problems.
UPDATE tbl
SET field=newValue
WHERE tbl.key IN
(SELECT idNew FROM
(Select tbl.key AS idNew
FROM tbl
WHERE field=editValue) AS tblNew);
tbl - Table name being updated
field - Target field for update
newValue - Value to replace items in the target field
tbl.key - Field name for the key in your table
idNew - New name for key in your table, to replace the name and prevent failure from duplicating names in query. could be any alphanumeric string. 'id' or 'id_new' or 'id_n'
editValue - The value to change
tblNew - New name for query, to prevent duplicate table names in the query. Could be any alphanumeric string 'tbl_n' or 'tbl_new' or 'tbl_test'
This query gets the key values for all the records that match records that have values you want edited, then changes the names of the key and tbl so they can be processed by MySQL, lastly the update query runs and changes the values based on the keys provided in the sub-query.
Hopefully this saves someone else a few hours!

MySQL : multiple column values as 1 comma-separated string?

Suppose I have a select query like :
SELECT * FROM tablename
and in the table are columns : field1, field2 and field3
Does anyone know if it's possible to get a resultset with only 1 row with 1 field, with comma separated values of the columns, like this :
"fieldvalue1, fieldvalue2, fieldvalue3"
Problem is that I don't know the column names of the table in advance...
Another problem is that a prepared statement is not the way to go, since all this should be done from within a trigger, and MySQL doesn't allow dynamic cursors/selects inside a trigger.
I have done some research and only came as far as GROUP_CONCATenating the column names correctly. But the problem is, that
SELECT (SELECT GROUP_CONCAT( cols.column_name) FROM (SELECT column_name FROM information_schema.columns WHERE table_name='test_table') as cols) FROM test_table
will return one and the same concatenated string containing the column names, once for each table row, instead of evaluating it as the column names for the outer select statement and returning the actual values.
From what I have read in all of the forums discussing this kind of question (and there were many), there is really no way of getting this to work without prepared statements.
I can only think of one other way to do this, and that would be having a dedicated column on each table, where you concatenate the individual column values on INSERT or UPDATE, so you can simply select this one field instead of the full set of fields.
Seems like you have 3 questions here:
Getting a resultset with 1 row, 1 field: MYSQL has a CONCAT_WS function that works like this:
SELECT CONCAT_WS(',',Field1,Field2,Field3)
That will return "Field1Value, Field2Value, Field3Value"
I'm not sure how you are going to get these column names. Do you need to get them from a sql statement, a string, etc. ? You can get the table names `SHOW COLUMNS FROM tablename'. The Field column will have the column names.
Triggers are available in mysql (added in 5.0.2 I think): http://dev.mysql.com/doc/refman/5.0/en/triggers.html
First, to find out the columns' names in advance, assuming that you have the table's name, you can get them as any other query:
SHOW COLUMNS FROM your_table
Once you have the names you can do:
SELECT CONCAT(field1,',',field2,',',field3) AS newField FROM your_table