Read-only after inner join (MySQL) - mysql

In MySQL workbench (Mac OS), I wanted to join two tables so that I can update the second one. The code I put in was as follows
select f.company, f.remarks, c.pic
from feedback f, customers c
where f.col = c.col
order by f.company;
The output is a read only table, which prevented me from updating table "customers" based on the f.remarks column.
Your advice/suggestion is appreciated. Thank you.

By hovering above the "Read Only" icon, I got the following message:
"Statement must be a SELECT from a single table with a primary key for its results to be editable".
After some research based on the advice given by fellow coders, here are some points to note:
In MySQL workbench, one cannot edit the results obtained from any JOINs because it's not from a single table;
In using SELECT from a single table, the primary key must be included in order for the result to be editable.
Thank you to everyone who contributed to the question. I appreciate it.

The problem is because, as you mentioned, SELECT only returns a "read only" result set.
So basically you cant use MySQL workbench to update a field in a read only result set that is returned when using a JOIN statement.

from what i understand you want to update table "customers" based on a query.
maybe this post will help you:
update table based on subquery of table

Related

Making a custom table from one table

My table is called Storage_Tot which has date, tagid, value components.
Below are the two tables (Table A and Table B) I created using SQL query. I essentially ran same query with different tagid with the same table 'Storage_Tot). I would like to combine table A and B and also add a 3rd column which is the sum of the values of Table A and Table B (Table C).
Table A (Left table) Table B (Right Table)
enter image description here
Here is the sample query that I wrote for the two tables.
enter image description here
This is how I would like my final table to look like. As a first step I was trying to just combine the the values of Table A and Table B and after that focus on the arithmetic aspect.
enter image description here
Here is the SQL query when combing the two tables but it does not work
enter image description here
_______________________________________ APPEND
Since I couldn't post under the response question, After implementing your suggestion here is the error that I get.
enter image description here
This is how the query looks as it sits and it appears that its not like where Storage_Tot.TagID = 106
enter image description here
I believe what you are asking for is (1) a JOIN and (2) a calculated column.
Here's the general idea for a JOIN:
SELECT
tblA.date, tblA.value, tblB.value
FROM
(SELECT * FROM Storage_Tot WHERE tagid = 'TABLEA_TAGID') tblA
INNER JOIN
(SELECT * FROM Storage_Tot WHERE tagid = 'TABLEB_TAGID') tblB
ON (tblA.date = tblB.date);
Some of that is guesswork, because you didn't provide complete details in your question. But hopefully you can see what's going on: the sub-queries in a way 'create' what you are calling the two tables shown in your first image.
Now, to add a total, just add a calculated column to the above query:
SELECT
tblA.date, tblA.value, tblB.value, tblA.value + tblB.value AS total_value
I have not verified any of this in an instance of MySQL, but I do believe I have the syntax correct for MySQL. You might need to make small adjustments for typos.. I have verified the above syntax via SQL Fiddle. Of course you need to fill in what TABLEA_TAGID and TABLEB_TAGID really are.
There are also lots of tutorials and references for using JOINs on-line. There are various kinds of JOINs, and I'm only showing one kind here.
#landru27: Thank you so much for your help. I don't know how I missed that from/where syntax. Anyway, I took your direction and had to make minor changes and the code executed.
Below is the final code that I shall be using for my query.
enter image description here

How To Joining 2 Table Not Well-Formatted With Complex Condition and WildCard

Recently I am using MySQL as database for small tasking to joining 2 table like below:-
But I have problem regarding complexity query and some of data are not well-formatted like table A.Bill_No (01X) ---> B.No (1X) where "0"1X are not appear as value on column table B.No
I also need to choose on B.From = ''ext'' only as condition WITH longest Duration as you can see desired output like below:-
I don't have idea how to create query statement like that output but I am hoping anybody on this forum please help me if you facing a same problem like I am now.
Anyway thanks very much on advance for read and replying this question.
I have a small progress to archive my output where I use SUBSTRING to equalize some value are not well-formatted as #Gordon Linoff mention earlier. To archive that I use the sql statement like below:-
Select
a.id,
b.no
From
a Inner Join
b On SubString(a.bill_no From 2 For 8 ) = b.no
Now, I need to filter the longest one duration for each ID if have more than one record on Table B to completed my query.
Please forums give me some advice to archive that, your kindness and helping I am are really appreciated.

MSQL alter table with JOIN

I am trying to update a table with a column from another table. I dont want to view the join, I want to alter the table.
However, this is faiing:
UPDATE
a_dataset
SET
a_dataset.lang_flag = b_dataset.language
FROM
a_dataset
INNER JOIN
b_dataset
ON
a_dataset.ID = b_dataset.ID
However, I keep getting a syntax error, and cannot locate what I am missing?
I am guessing that you mean to update your records when you say alter the table. If so, you can simply rewrite your update statement with join like this:
UPDATE a_dataset a
JOIN b_dataset b ON a.ID = b.ID
SET a.lang_flag = b.[LANGUAGE]
As Uueerdo and myself said: Starting table names with numbers is a bad[TM] idea. The same is for letters, which you now chose to use. a is no better than 1 in this regard. Also calling tables just "dataset" isn't really helpful either. What is the table storing? Users? Then call it users. Articles on a news web site? Then call it articles. And so on. Everything in a database is dataset, no need to tell that anyone.
I guess you're new to SQL, am I right? Because another issue is: Unless you're going to drop table b_dataset after this command, you're probably doing something you're not supposed to do in relational data bases. The whole idea is to store all data only once. If you can automagically copy the column from b to a, then you could also select join if from a and b when you need it instead of copying it.
For learning SQL (or anything else), Stack Overflow is probably a bad place (it's good for asking questions in the process, though), so I recommend that you go get someone who has some experience in SQL to teach you, or get some book / tutorial on SQL. From first glance, this seems to be a good on-line book: http://sql.learncodethehardway.org/ - but I didn't read it.

Set two values in one table based on sum of a column in another table

I have two tables, a "data" table with hundreds of thousands of rows, and a "settings" table with hundreds of rows. I need to update two values in the settings table, based on the sum of one column in the data table being greater than another column in the settings table, where the 'id' of the settings table matches the 'offerid' of the data table.
I've been cruising Google looking at many possible solutions, but I don't seem able to bend any of them to my needs. Any time I start working with Joins, I inevitably get tripped up.
My latest attempt which did not work, is:
UPDATE settings a, data b
SET a.hidden=1, a.weight=0
WHERE a.id = b.offerid
AND sum(b.views) > a.target
I liked this flavor of approach as I thought it actually made sense to me, but all I get is "Error code 1111: Invalid us of group function". Maybe someone here can point me in the right direction.
It errors out because you are using an aggregate function (sum) with no grouping. So query really does not know which rows should be summed together. You can use a subquery like this:
UPDATE settings a
INNER JOIN
(
SELECT
sum(b.views) sumviews, b.offerid
from data b
group by b.offerid
) c on c.offerid = a.id
SET a.hidden=1, a.weight=0
where c.sumviews>a.target
EDIT: To disable the safe update function do the following steps
Follow the steps below before executing the UPDATE command:
Go to Edit --> Preferences
Click "SQL Queries" tab and uncheck "Safe Updates" check box
Query --> Reconnect to Server
Now execute your sql query
Source: Disable Safe Update
Try using
HAVING
instead of
AND
So your code goes like:
UPDATE settings a, data b
SET a.hidden=1, a.weight=0
WHERE a.id = b.offerid
GROUP BY a.id
HAVING sum(b.views) > a.target

Optimized SELECT query in MySQL

I have a very large number of rows in my table, table_1. Sometimes I just need to retrieve a particular row.
I assume, when I use SELECT query with WHERE clause, it loops through the very first row until it matches my requirement.
Is there any way to make the query jump to a particular row and then start from that row?
Example:
Suppose there are 50,000,000 rows and the id which I want to search for is 53750. What I need is: the search can start from 50000 so that it can save time for searching 49999 rows.
I don't know the exact term since I am not expert of SQL!
You need to create an index : http://dev.mysql.com/doc/refman/5.1/en/create-index.html
ALTER TABLE_1 ADD UNIQUE INDEX (ID);
The way I understand it, you want to select a row with id 53750. If you have a field named id you could do this:
SELECT * FROM table_1 WHERE id = 53750
Along with indexing the id field. That's the fastest way to do so. As far as I know.
ALTER table_1 ADD UNIQUE INDEX (<collumn>)
Would be a great first step if it has not been generated automatically. You can also use:
EXPLAIN <your query here>
To see which kind of query works best in this case. Note that if you want to change the where statement (anywhere in the future) but see a returning value in there it will be a good idea to put an index on that aswell.
Create an index on the column you want to do the SELECT on:
CREATE INDEX index_1 ON table_1 (id);
Then, select the row just like you would before.
But also, please read up on databases, database design and optimization. Your question is full of false assumptions. Don't just copy and paste our answers verbatim. Get educated!
There are several things to know about optimizing select queries like Range and Where clause Optimization, the documentation is pretty informative baout this issue, read the section: Optimizing SELECT Statements. Creating an index on the column you evaluate is very helpfull regarding performance too.
One possible solution You can create View then query from view. here is details of creating view and obtain data from view
http://www.w3schools.com/sql/sql_view.asp
now you just split that huge number of rows into many view (i. e row 1-10000 in one view then 10001-20000 another view )
then query from view.
I am pretty sure that any SQL database with a little respect for themselves does not start looping from the first row to get the desired row. But I am also not sure how they makes it work, so I can't give an exact answer.
You could check out what's in your WHERE-clause and how the table is indexed. Do you have a proper primary key? Like using a numeric data type for that. Do you have indexes on more columns, that is used in your queries?
There is also alot to concider when installing the database server, like where to put the data and log files, how much memory to give the server and setting the growth. There's a lot you can do to tune your server.
You could try and split your tables in partitions
More about alter tables to add partitions
Selecting from a specific partition
In your case you could create a partition on ID for every 50.000 rows and when you want to skip the first 50.000 you just select from partition 2. How to do this ies explained quite well in the MySQL documentation.
You may try simple as this one.
query = "SELECT * FROM tblname LIMIT 50000,0
i just tried it with phpmyadmin. WHERE the "50,000" is the starting row to look up.
EDIT :
But if i we're you i wouldn't use this one, because it will lapses the 1 - 49999 records to search.