MySQL insert into (conditionally selected table) in single statement - mysql

My dbm knowledge is still pretty limited, so I am not sure how to approach/solve this problem. I want to INSERT INTO one of two tables, say, table1 and table2, but I don't know which table until after a SELECT subquery. Something like this:
INSERT INTO (SELECT tblname) SELECT *, IF(somecondition, 'table1', 'table2') as tblname FROM `anothertable` WHERE id = 'someid'
I tried this as a test:
INSERT INTO (SELECT tblname) SELECT *, 'table1' as tblname FROM `anothertable` WHERE id = 'someid'
But that didn't work.
I know I can use subqueries in SELECT statements (so useful!), and that I can technically achieve what I want with NOT EXISTS in 2 statements, and I know I cannot INSERT into two tables, and I know that using # user variables is unreliable within a statement (see docs). So, is there a way to achieve what I want, in a single statement?

you can do it with case statement.
SELECT CASE WHEN ( SELECT IF(somecondition, 'table1', 'table2') as tblname FROM `anothertable` = 'table1' )
THEN <QUERY A>
ELSE <QUERY B>
END

Related

How do select data with IF ELSE statement in a MySQL query

I get data from MySQL with if statement as code below. but I get an error:
Error Code: 1241. Operand should contain 1 column(s).
so can someone can help me?
I can not put it into the procedure, because I am using spring + mybatis in the project and i will put this code into them.
SELECT IF((SELECT COUNT(*) FROM table1 WHERE someField = 'A') < 0,
(SELECT * FROM table2 WHERE someField = 'A'),
(SELECT * FROM table1 WHERE someField = 'A'))
From the comments: I wanna get data of 1 in 2 tables when table 1 don't have data I will get data from table 2.
That sounds like union all and not exists:
select * from table1 where someField = 'A'
union all
select * from table2 where not exists(select 1 from tabe1 where someField = 'A'
Note that, for this to work, both tables must contain exactly the same number of columns, whith aligned datatypes. You should really be enumerating the columns that you want to show in the resultset in both unioned queries, to avoid any possible ambiguity. If needed, you can cast columns or add litteral values to any or both of the resultset to align the resultsets (without seeing your actual data structures, I cannot tell how to do).

Split the values from ('1,2,3') to ('1','2','3') or (1,2,3) in sql

I have a table field named category_ids (text) which saves another table's ids as "1,2,3".
Now i want to use this category_ids to a sql IN() query. the query will be like tab1.category_id IN (select category_ids from tab2). but i'm facing issue as select category_ids from tab2 returns '1,2,3' so IN() query not working.
Is there any simple way to convert '1,2,3' to ('1','2','3') or (1,2,3) in sql?
You may use FIND_IN_SET here:
SELECT *
FROM tab1
WHERE FIND_IN_SET(tab1.category_id,
(select category_ids from tab2));
This is just a sample query, your actual one may differ. But the point is that if you want to search for '1' inside a CSV string '1,2,3', then there is a way to do it.
As others have already mentioned, you should avoid storing CSV data in your tables. When I see FIND_IN_SET being heavily used there is usually a smell.
try
tab1.category_id IN (select REPLACE(category_ids, '''', '') from tab2)
If table2 has more than one row, you can use exists with find_in_set():
select t1.*
from table1 t1
where exists (select 1
from table2 t2
where find_in_set(t1.category_id, t2.category_ids) > 0
);
Note that this is a very poor data structure. You should have a single row for each category id in table2. If you did, then the query would be simpler and have better performance.

How can I implement a "complex" INSERT query that retrieve the values calling other queries?

I am not so into database and maybe I am saying something trivial.
I am working on MySql and I have to implement a "complex" INSERT query.
I mean that I have to do something like this:
INSERT INTO MarketDetails_CommodityDetails
(market_detail_id, commodity_detail_id) VALUES
( XXX, YYY)
where XXX and YYY are not simple values but are the results of two SELECT queries both returning a single value (XXX is return by a SELECT query and YYY by another query).
I know that I can perform these queries, store the output in a variable and then call my insert query passing these parameters but I am asking if there is a way to automatically do it into my INSERT query.
Why do you want to use insert values ?
just perform an insert select
INSERT INTO MarketDetails_CommodityDetails(market_detail_id, commodity_detail_id)
select * from
(select --Complex select for XXX)
cross join
(select --Complex select for YYY)
You could also use values if you wanted to. Make sure you use 2 parenthesis instead of just 1 and make also sure to use limit statement even if your query always returns 1 row.
INSERT INTO some_final_table (column1, column2) VALUES (
(SELECT some_column_1 FROM some_middle_table_1 LIMIT 1),
(SELECT some_column_2 FROM some_middle_table_2 LIMIT 1)
)

How do I execute a query using INSERT INTO and WITH statement?

INSERT INTO tablename( columnname1, columnname2, columnaname2)
WITH
a AS
SELECT * FROM tablename
WHERE condition
),
b AS
SELECT * FROM tablename
WHERE condition
)
I have a couple lines of query below where I use an DISTINCT statement but would like to know for now whether my query above is correct or not.
WITH? This is going to be introduced in MySQL 8.0. Are you using a preview release? Otherwise you won't be able to use WITH in MySQL.
Anyway: A WITH clause belongs at the beginning of the statement: WITH ... INSERT .... See here: https://dev.mysql.com/doc/refman/8.0/en/with.html.
It seems, however, you are not even using your CTEs a and b. Your CTEs are also lacking parentheses. Your statement should look something like this for instance:
WITH a AS (SELECT * FROM tablename WHERE condition)
, b AS (SELECT * FROM tablename WHERE condition)
INSERT INTO tablename(columnname1, columnname2, columnaname2)
SELECT col1, col2, col3 FROM a
UNION ALL
SELECT col1, col2, col3 FROM b;

Select record using values from a previous COUNT() IN MYSQL

I obtain a series of values that appear only one time in my database using COUNT in mysql that list below:
valueName
---------
value1
value2
value3
value4
I need a script that retrieves all records in a table where valueName are not the values listed in the initial count, and I need this two steps to run in a single script (doesn't matter how many parts it has).
I've got the script to obtain the list above like this:
SELECT field AS new_name FROM table GROUP BY field HAVING COUNT(field) = 1;
And it works.
The problem is that I don't know how to work with the aggregated result of the first step. Maybe using some kind of function. Or loop (I don't think in SQL..).
I've tried different things like attaching a COUNT inside a WHERE clause and others but it doesn't work.
Please help!
Use a join:
select t.*
from table t join
(SELECT field
FROM table
GROUP BY field
HAVING COUNT(field) > 1
) filter
on t.field = filter.field;
If you have a primary key in your table and an index on table(field, pk), the following is probably faster:
select t.*
from table t
where exists (select 1
from table t2
where t2.field = t.field and t2.pk <> t.pk
);
Try this:
SELECT table.* FROM table
JOIN
(SELECT field FROM table GROUP BY field HAVING COUNT(field) > 1) newtable
ON
table.field = newtable.field;
This should work.