Dynamically pick field to select data from - mysql

Say I have a table with three columns primaryNum, secondaryNum, chosenNum. primarynum and secondaryNum are both number values but chosenNum's value can either be "primaryNum", "secondaryNum", or "both".
The chosenNum field is a column that gives me the option to search for a number in a particular field.
For example: I might want to try to find all rows with the value 10 in the column that is stored in chosenNum. If the value of chosenNum is "both" then the row would be returned if either column (primaryNum, secondaryNum) had a value of 10.
What might my select statement look like?
It might be a better scenario if I say I would like to do a select statement like:
SELECT * FROM aTable WHERE (SELECT bVal FROM bTable WHERE aVal = #varField ) = 0;
Where #varField is the value of the value in the field with the label stored in chosenNum or either field if chosenNum = "both"
This would result in me getting back rows with id 1,2,3,4,6,7,14,15,16,19,20,21,23,24,27
Table A: Create
CREATE TABLE `test`.`aTable` (
`id` INT NOT NULL AUTO_INCREMENT ,
`primaryNum` INT NULL ,
`secondaryNum` INT NULL ,
`chosenNum` CHAR(12) NULL ,
PRIMARY KEY (`id`) );
Table B: Create
CREATE TABLE `test`.`bTable` (
`aVal` INT NULL ,
`bVal` INT NULL );
Table A: Data
INSERT INTO test.aTable VALUES (1,8,7,'secondaryNum'),(2,2,9,'secondaryNum'),(3,7,9,'both'),(4,5,1,'both'),(5,10,3,'secondaryNum'),(6,10,6,'both'),(7,7,8,'both'),(8,10,2,'primaryNum'),(9,2,1,'secondaryNum'),(10,7,2,'secondaryNum'),(11,2,2,'secondaryNum'),(12,5,1,'secondaryNum'),(13,1,6,'primaryNum'),(14,6,6,'both'),(15,4,9,'both'),(16,9,7,'primaryNum'),(17,8,3,'secondaryNum'),(18,10,7,'primaryNum'),(19,8,5,'secondaryNum'),(20,1,7,'both'),(21,7,9,'both'),(22,8,3,'primaryNum'),(23,6,2,'primaryNum'),(24,5,7,'both'),(25,2,1,'both'),(26,5,2,'secondaryNum'),(27,7,8,'primaryNum');
Table B: Data
INSERT INTO test.bTable VALUES (1,1),(2,1),(3,1),(4,1),(5,0),(6,0),(7,0),(8,1),(9,0),(10,1);

You can do something like this:
select *
from MyTable
where (chosenNum in ('both', 'primaryNum') and primaryNum = 10)
or (chosenNum in ('both', 'secondaryNum') and secondaryNum = 10)

Related

How do I insert data into a table (and return it) when a select statement outputs no rows?

I have a MySql table that is created like this;
CREATE TABLE test_contacts
(
id int PRIMARY KEY AUTO_INCREMENT,
name varchar(16) NOT NULL,
databit int NOT NULL
);
CREATE UNIQUE INDEX test_contacts_name_uindex ON test_contacts (name);
When I want to retrieve data i do SELECT * FROM test_contacts WHERE name = '{name}';
In my current java application I am doing the following: (pseudocode)
Object result = SELECT * FROM test_contacts WHERE name = '{name}';
if (result == null) {
INSERT INTO test_contacts (`name`, `databit`) VALUES ('{name}', 2);
result = SELECT * FROM test_contacts WHERE name = '{name}';
}
Is there a way to compact these 3 database calls into 1 statement that always returns a row for the specified name? (I need the id that is inserted)
Since you have a unique index anyway, instead of checking in your code, if your first select had any result, you simply do
INSERT IGNORE test_contacts (`name`, `databit`) VALUES ('{name}', 2);
read more about it here
Then you get the id with
SELECT LAST_INSERT_ID();
read more about it here

insert a new record into a mysql table with one of the values incremented by 1

I've got the following table:
productId price
1 price_value1
2 price_value2
3 price_value3
I would like to insert a new product into the table and assign it a new productId. In this case its value equals to 4.
So I want my new table to look like so:
productId price
1 price_value1
2 price_value2
3 price_value3
4 price_value4
So as far as I understand, in order to do that I have to somehow retrieve the max value of productId and insert it using INSERT INTO mytable VALUES (productId + 1, price_value4).
But how do I find out the maximum value of productId?
I tried INSERT INTO mytable VALUES (SELECT MAX(productId) + 1 FROM mytable, price_value4) but it didn't work.
This should Work:
Select the max(productID) and price_value4 as a columns from mytable and insert the result.
INSERT INTO mytable (SELECT MAX(productId) + 1, 'price_value4' FROM mytable);
However, if you are not going to jump some number you can just add an auto increment id key to product_id and then you will have only to insert the price, the product ID will be incremented automatically..
This will do so :
ALTER TABLE mytable
MODIFY COLUMN `productId` INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT;
you can change INT(10) with the INT(5) for example depanding on the size you want to give to your productId column
EDIT :
In return to the OP question in comments why his solution wouldn't work
Some suggetions says you have to make the SELECT statment in insert always between parenthesis
INSERT INTO mytable VALUES ( (SELECT MAX(ID)+1 FROM mytable) , price_value4)
.. In my Case it Return
(1093): You can't specify target table
'mytable' for update in FROM clause
AND HERE IS WHY (Quoting From the documentation)
When selecting from and inserting into the same table, MySQL creates
an internal temporary table to hold the rows from the SELECT and then
inserts those rows into the target table. However, you cannot use
INSERT INTO t ... SELECT ... FROM t when t is a TEMPORARY table,
because TEMPORARY tables cannot be referred to twice in the same
statement
BUT there is away to overcome by using a query instead of the table itself in the FROM, which has the effect of copying the requested table values instead of referencing the one that you are updating..
INSERT INTO mytable VALUES (
(SELECT MAX(ID)+1 FROM (SELECT * FROM mytable ) as mytmp ),
'price_value4');
OR (Quoting From the documentation)
To avoid ambiguous column reference problems when the SELECT and the
INSERT refer to the same table, provide a unique alias for each table
used in the SELECT part, and qualify column names in that part with
the appropriate alias.
INSERT INTO mytable Values ( (SELECT MAX(ID)+1 FROM mytable as mytmp) , 'price_value4')
This is a duplicate question. In order to take advantage of the auto-incrementing capability of the column, do not supply a value for that column when inserting rows.
A simple syntax to create table
CREATE TABLE Product (
productId MEDIUMINT NOT NULL AUTO_INCREMENT,
price INT NOT NULL,
PRIMARY KEY (productid)
);
While inserting supplied default or leave column as blank or supplied value as NULL. Take a look at below code snippet.
INSERT INTO Product (price) VALUES
('10'),('20'),('4'),
('30');
refer this link

Rename columns in SQL

I want to (directly) generate a table with the content from 2 columns of another table. How ca I change the names of the columns (rename them in the new table)?
Here´s an example:
CREATE TABLE X AS
SELECT
Table1.name,
Table1.act
FROM Y
->I don´t want to name the columns "name" and "act" as in the original table - I want to have "name" replaced by "customer" and "act" replaced by "status"
Do it like this:
CREATE TABLE X AS
SELECT
Table1.name as customer,
Table1.act as status
FROM Y
You could just specify name aliases in the query:
CREATE TABLE X AS
SELECT
Table1.name AS customer,
Table1.act AS status
FROM Y
Alternatively, you could specify the column definitions in brackets after the table name:
CREATE TABLE X (customer VARCHAR(10), status VARCHAR(10)) AS
SELECT
Table1.name,
Table1.act
FROM Y
You will need to use a While Loop to do that:
$my_query = "SELECT * FROM tj_ethnicity FROM Table_X";
while($row = mysql_fetch_assoc($my_query))
{
$new_query = "CREATE TABLE `."$row['customer']".` (
`customerid` int(11) NOT NULL AUTO_INCREMENT,
`status` varchar(50) DEFAULT ."$row['status']".,
`created` datetime NOT NULL,
PRIMARY KEY (`customerid`)
)";
}

Sql decimal values not geting stored in temporary table

I am creating empty temporary table based on another table in my db and adding an extra column (PRICE) which i am trying to populate from query,
SELECT TOP 0 ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber,
ID,
NULL AS PRICE
INTO #TMP_TABLE
FROM SQL_TABLE
when i fill this table as INSERT INTO #TMP_TABLE ... the value i am getting in PRICE column is either 0 or 1, but when i execute query seperately, i am getting decimal values (like0.0634).
how can i store decimal values in temp table above ? or is there any other way to create empty temp table ?
Use CREATE TABLE and define explicitly columns types:
CREATE TABLE #TMP_TABLE(RowNumber INT, ID <you_type>, Price <your_type>)
Default for NULL is INT, check:
SELECT x = NULL INTO #x;
EXEC tempdb..sp_columns '#x';
So your fraction are converted implicitly to INT
One good rule for future EXPLICIT IS ALWAYS BETTER THAN IMPLICIT
you either create the table with a create table statement:
create table #TMP_TABLE
( RowNumber int
, ID <whatever datatype>
, PRICE numeric(10,2)
);
or if you insist on select into declare the datatype :
SELECT TOP 0 ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber,
ID,
cast(NULL as numeric(10,2)) AS PRICE
INTO #TMP_TABLE
FROM SQL_TABLE

Select statement involving SET data type

How to use the SET datatype in MySQL? I have a table Train in which there are fields
trainno int
Weekdays set data type
Stops set data type
train name
How to write a select query where I can compare the Stops set with a particular value like 'Mumbai'?
Create a table like:
CREATE TABLE cl_db.Train
(
trainno INT PRIMARY KEY AUTO_INCREMENT,
Stops set('aaa','bbb','ccc') NOT NULL
)
and you can query it like
select * from cl_db.Train where Stops like 'bbb'
or like
select * from cl_db.Train where FIND_IN_SET('bbb',Stops)>0;