How do I copy content from one table with a where clause to the same table to another where clause?
So the Select Query would be:
SELECT * FROM items WHERE countryNr=5;
I want now to insert all data from the above query into for example countryNr=1.
So countryNr=5 and CountryNr=1 should habe in the end the same data.
What you have described is more like an UPDATE than INSERT...
in that case your query could be something like this:
update item
set (field1, field2) = (select field1, field2 from item where countrNR = 5)
where countrNR = 1
I'm not sure I understand the question but something like... mySQL docs for insert into select
Insert into items Select Field1, Field2, Field3, Field4..., 1 as countryNR
from items where countrNR = 5
Related
Before running a REGEXP_REPLACE on a big table, I want to preview the results, so I want to copy the 'before' and 'after' of the modified field to another table so I can audit.
What's the best way to do this?
Something like
INSERT INTO table2 (before, after)
SELECT field1, REGEXP_REPLACE(field1,'foo','bar')
FROM table1
WHERE condition
(MariaDB)
If this were my project I'd do these things.
First. Just do this and eyeball the results.
SELECT COUNT(*), field1, REGEXP_REPLACE(field1,'foo','bar')
FROM table1
WHERE field1 <> REGEXP_REPLACE(field1,'foo','bar')
GROUP BY field1, REGEXP_REPLACE(field1,'foo','bar')
ORDER BY COUNT(*), field1
That will show you the least frequent values first so you can see the one-off problems caused by your replace first. No need to create a table.
Second, I'd eyeball the values that DIDN'T change with this, changing the WHERE clause from <> to =.
SELECT COUNT(*), field1
FROM table1
WHERE field1 = REGEXP_REPLACE(field1,'foo','bar')
GROUP BY field1
ORDER BY COUNT(*), field1
Maybe some stuff didn't change that should have.
Edit SQL can get a little verbose. If you're fiddling around with some complex conversion functions you might try creating a view. Something like this:
CREATE OR REPLACE VIEW testview AS
SELECT field1,
REGEXP_REPLACE(field1,'foo','bar') changed
FROM table1;
Then you can do
SELECT COUNT(*), field1, changed
FROM testview
WHERE field1 <> changed
GROUP BY field1, changed
ORDER BY COUNT(*), field1;
And similar queries. If you must change your replace function, you can edit the view definition and do the CREATE OR REPLACE again.
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)
)
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
suppose I do this:
SELECT * FROM table WHERE field2 = '2019#162440' OR field2 LIKE '%%2019#%%';
In this case, it will try to execute the matching of BOTH field2 = '2019#162440'and field2 LIKE '%%2019#%%' conditions (ie, it will search for rows matching those conditions hence it takes some more computation power to try to find rows matching both condition even if it already found a row matching field2 = '2019#162440')
Is there a way to instruct mysql by reforming the query to ONLY try to execute field2 LIKE '%%2019#%%' if the condition field2 = '2019#162440' does not match anything so that the query becomes more efficient
IE. I essentially want mysql to only try to find rows matching field2 LIKE '%%2019#%%' only if no rows match field2 = '2019#162440'. If a row that matches field2 = '2019#162440' is found, do NOT try to match field2 LIKE '%%2019#%%'
Also, no subqueries
Let me start by stating that I am not an expert in MySQL. It is not nearly as optimized as some other DBMSes, so the following query might not actually reduce your execution time. But it's worth a shot...
If field2 is indexed, this might be a really fast solution:
-- Get results where field2 = '2019#162440'
SELECT *
FROM table
WHERE field2 = '2019#162440'
-- Append...
UNION
-- Get results where field2 LIKE '%%2019#%%' but only
-- if there are no rows where field2 = '2019#162440'
SELECT *
FROM table
WHERE NOT EXISTS(
SELECT *
FROM table
WHERE field2 = '2019#162440'
)
AND field2 LIKE '%%2019#%%'
You are going to run your fastest query and select all results. Then, append the second, slower query which contains an EXISTS. The EXISTS clause will return true if the subquery contains any rows, which should short-circuit the entire second query and prevent it from runnning (thus appending 0 rows). If the first query returns 0 rows, however, then the second query will kick in and run the slower LIKE comparisons.
The best I can do is use the FOUND_ROWS() function along with a UNION:
SELECT *
FROM t
WHERE field2 = '2019#162440'
UNION ALL
SELECT *
FROM t
WHERE FOUND_ROWS() = 0
AND field2 LIKE '%%2019#%%'
SQL Fiddle Demo
Using laravel/fluent query builder, I'm trying to cause a constant field value to pass through for a union(ed) selection that is subsequently ordered . I haven't found the recipe to do the following with fluent. The unions are easy, but how do you get the field constant to work?
Imagine two simple tables (omitted) and a union select:
select field1, field2, 'type1' as field3 from table1
UNION
select field1, field2, 'type2' as field3 from table2
ORDER BY field2
The best answer I've come up with so far, is to use a DB::query with a query string I manufacture myself. Laravel/fluent does not seem ready to handle this case, given the test cases I've tried. Using RAW for a select works great, until you try to order the pair of selected table queries.
SELECT field1, field2 FROM
(
SELECT fld1A as field1, 'FOO' as field2 from table1
UNION ALL
SELECT fld2A as field1, 'BAR' as field2 from table2
)
temp_table order by somefield
Using Laravel 4, and using GROUP BY, rather than ORDER BY I believe you can do something like:
$t1 = DB::table('table1')
->select('field1',DB::raw("'FOO' as field2"))
->groupBy('field2');
$t2 = DB::table('table2')
->select('field1',DB::raw("'BAR' as field2"))
->groupBy('field2');
$result = $t1->union($t2)->get();
I found that $t1 in this case can be an instance of Illuminate\Database\Query\Builder or Illuminate\Database\Eloquent\Builder, but the union argument ($t2) must be of type Illuminate\Database\Query\Builder.
This means that you may use eager loading with something like:
$t1 = MyTableModel::with('table3')->select...
This way, probably:
$users = DB::table('users')
->select(DB::raw("'FOO' as field2"))
->get();