Comparing 2 identical MySQL tables - mysql

I have 2 indentical tables called LIVE and BACKUP.
What I cam trying to do is to compare a LIVE record with its equivalent BACKUP record to see if they match. This check is required each time an individual LIVE record is accessed.
i.e. I only want to compare record number 59 (as an example) rather than all records in the LIVE table?
Currently I can do what I want by simply comparing the LIVE record and its equivalent BACKUP record on a field by field basis.
However, I was wondering if it is possible to do a simple "Compare LIVE record A with BACKUP record A".
I don't need to know what the differences are or even in which fields they occur. I only need to know a simple yes/no as to whether both records match or not.
Is such a thing possible or am I stuck comparing the tables on a field by field basis?
Many thanks,
Pete

Here is a hack, assuming the columns really are all the same:
select count(*)
from ((select *
from live
where record = 'A'
) union
(select *
from backup
where record = 'A'
)
) t
This will return "1" if they are identical and "2" if more than one record exists. If you want to ensure against two values being in the same table, then use the modified form:
select count(distinct which)
from ((select 'live' as which, l.*
from live .
where record = 'A'
) union
(select 'backup' as which, b.*
from backup b
where record = 'A'
)
) t;
Also . . . Note the use of union. The duplicate removal is very intentional here.

Related

Store a data record into another table if it does not exist

I am looking for a SQL code that is doing the following thing:
SELECT * FROM fzs_contest WHERE answer = 'D' order by rand() limit 1;
Store the result of the code above to the table fzs_contest_winners (create the table if it does not exist)
If the data record already exists in the table fzs_contest_winners, reapeat line #1 until it is unique.
Is that possible with SQL only?
How about just getting a valid winner the first time?
insert into fzs_contest_winners ( . . .)
select . . .
from fzs_contest c
where answer = 'D' and
not exists (select 1 from fzs_context_winners cw where cw.?? = c.??)
order by rand()
limit 1;
The ?? is for the column that identifies someone as being the same in the two tables.
Note: This type of query could choose the same winner twice, if two threads were running at the same time. However, it seems unlikely to me that you are selecting more than one winner at a time. In addition, you should guarantee that a person only appears once in the table by using a unique index.

Check what table a record belongs in using MySQL

I have a requirement to check what table a record belongs in out of 2 tables and set a variable depending on the returned table.
e.g. I have 2 tables (tbl_registered_users, tbl_unregistered_users). If I search for an email address that existed in tbl_registered_users I would like the query to return 'tbl_registered_users' so I can set a variable $whatTable = ... (for example).
I know I could do this with 2 queries or even 1 if I can guarantee the record will exist in at least one table however I would potentially like to use the query on 3/4/5/10 tables and on records that may not exist in any.
Thanks
You can use a UNION for that with a subquery:
SELECT *
FROM (
SELECT 'Registered' WhichTable, Email
FROM tbl_registered_users
UNION
SELECT 'UnRegistered', Email
FROM tbl_unregistered_users
) t
WHERE Email = 'emailaddress'
SQL Fiddle Demo
Using UNION ALL would yield a better performance, but it won't remove duplicates (in case you have duplicated data in either single table).

SELECT last 250 rows from a table with no auto id

I know there is a few posts out there already but some are conflicting.
I have taken on a project in which I have inherited a table with a few 1000 entries.
The problem is, there is no auto increment ID field on the table and I have been asked to extract the last 300 rows that were entered into it.
It it possible to extract the last 300 entries from a table? Is there a "systems row id"?
The strict answer is "no" unless you have a date or something else that indicates order. Tables are inherently unordered.
In practice, you generally fetch the data back in the order you put it in. The more true the statement, "I loaded the data once, with no subsequent inserts, into a system with only one processor and one disk", the more likely that the data is actually in order.
Having a system row id would not help you, because you might have deletes and subsequent inserts. A later record would be put in an earlier page, in this case.
You have a small table. Do a select *, copy the data into a spreadsheet and do the work from there.
Alternatively, you can select the table with an increasing row number, insert into another table, and then do the select from there. Something like this pseudocode:
insert into NewTable (seqnum, cols)
select :rownum=:rownum+1, cols
from YourTable
There is a chance you'll get what you want.
One last point. If you did inserts and have the log files since the inserts, you might be able to get the information from there. With a little work.
Try this:
SELECT col1, col2, ...
FROM (SELECT col1,col2, ..., (#auto:=#auto+1) indx
FROM tablename, (SELECT #auto:=1) AS a
) AS b
ORDER BY indx DESC
LIMIT 30
If you at least have a record insertion time in the table, then you can use this.. Otherwise no.
SELECT * FROM
yourtable
ORDER BY inserted_time desc limit 300;

Removing duplicate data from many rows in mysql?

I am a web developer so my knowledge of manipulating mass data is lacking.
A coworker is looking for a solution to our data problems. We have a table of about 400k rows with company names listed.
Whoever designed this didnt realize there needed to be some kind of unique identifier for a company, so there are duplicate entries for company names.
What method would one use in order to match all these records up based on company name, and delete the duplicates based on some kind of criteria (another column)
I was thinking of writing a script to do this in php, but I really have a hard time believing that my script would be able to execute while making comparisons between so many rows. Any advice?
Answer:
Answer origin
1) delete from table1
2) USING table1, table1 as vtable
3) WHERE (NOT table1.ID>vtable.ID)
4) AND (table1.field_name=vtable.field_name)
Here you tell mysql that there is a table1.
Then you tell it that you will use table1 and a virtual table with the values of table1.
This will let mysql not compare a record with itself!
Here you tell it that there shouldn’t be records with the same field_name.
The way I've done this in the past is to write a query that returns only the set I want (usually using DISTINCT + a subquery to determine the right record based on other values), and insert that into a different table. You can then delete the old table and rename the new one to the old name.
To find list of companies with duplicates in your table you can use script like that:
SELECT NAME
FROM companies
GROUP BY NAME
HAVING COUNT(*) > 1
And following will delete all duplicates except containing max values in col column
DELETE del
FROM companies AS del
INNER JOIN (
SELECT NAME, MAX(col) AS col
FROM companies
GROUP BY NAME
HAVING COUNT(*) > 1
) AS sub
ON del.NAME = sub.NAME AND del.col <> sub.col

What does it mean by select 1 from table?

I have seen many queries with something as follows.
Select 1
From table
What does this 1 mean, how will it be executed and, what will it return?
Also, in what type of scenarios, can this be used?
select 1 from table will return the constant 1 for every row of the table. It's useful when you want to cheaply determine if record matches your where clause and/or join.
SELECT 1 FROM TABLE_NAME means, "Return 1 from the table". It is pretty unremarkable on its own, so normally it will be used with WHERE and often EXISTS (as #gbn notes, this is not necessarily best practice, it is, however, common enough to be noted, even if it isn't really meaningful (that said, I will use it because others use it and it is "more obvious" immediately. Of course, that might be a viscous chicken vs. egg issue, but I don't generally dwell)).
SELECT * FROM TABLE1 T1 WHERE EXISTS (
SELECT 1 FROM TABLE2 T2 WHERE T1.ID= T2.ID
);
Basically, the above will return everything from table 1 which has a corresponding ID from table 2. (This is a contrived example, obviously, but I believe it conveys the idea. Personally, I would probably do the above as SELECT * FROM TABLE1 T1 WHERE ID IN (SELECT ID FROM TABLE2); as I view that as FAR more explicit to the reader unless there were a circumstantially compelling reason not to).
EDIT
There actually is one case which I forgot about until just now. In the case where you are trying to determine existence of a value in the database from an outside language, sometimes SELECT 1 FROM TABLE_NAME will be used. This does not offer significant benefit over selecting an individual column, but, depending on implementation, it may offer substantial gains over doing a SELECT *, simply because it is often the case that the more columns that the DB returns to a language, the larger the data structure, which in turn mean that more time will be taken.
If you mean something like
SELECT * FROM AnotherTable
WHERE EXISTS (SELECT 1 FROM table WHERE...)
then it's a myth that the 1 is better than
SELECT * FROM AnotherTable
WHERE EXISTS (SELECT * FROM table WHERE...)
The 1 or * in the EXISTS is ignored and you can write this as per Page 191 of the ANSI SQL 1992 Standard:
SELECT * FROM AnotherTable
WHERE EXISTS (SELECT 1/0 FROM table WHERE...)
it does what it says - it will always return the integer 1. It's used to check whether a record matching your where clause exists.
select 1 from table is used by some databases as a query to test a connection to see if it's alive, often used when retrieving or returning a connection to / from a connection pool.
The result is 1 for every record in the table.
To be slightly more specific, you would use this to do
SELECT 1 FROM MyUserTable WHERE user_id = 33487
instead of doing
SELECT * FROM MyUserTable WHERE user_id = 33487
because you don't care about looking at the results. Asking for the number 1 is very easy for the database (since it doesn't have to do any look-ups).
Although it is not widely known, a query can have a HAVING clause without a GROUP BY clause.
In such circumstances, the HAVING clause is applied to the entire set. Clearly, the SELECT clause cannot refer to any column, otherwise you would (correct) get the error, "Column is invalid in select because it is not contained in the GROUP BY" etc.
Therefore, a literal value must be used (because SQL doesn't allow a resultset with zero columns -- why?!) and the literal value 1 (INTEGER) is commonly used: if the HAVING clause evaluates TRUE then the resultset will be one row with one column showing the value 1, otherwise you get the empty set.
Example: to find whether a column has more than one distinct value:
SELECT 1
FROM tableA
HAVING MIN(colA) < MAX(colA);
If you don't know there exist any data in your table or not, you can use following query:
SELECT cons_value FROM table_name;
For an Example:
SELECT 1 FROM employee;
It will return a column which contains the total number of rows & all rows have the same constant value 1 (for this time it returns 1 for all rows);
If there is no row in your table it will return nothing.
So, we use this SQL query to know if there is any data in the table & the number of rows indicates how many rows exist in this table.
If you just want to check a true or false based on the WHERE clause, select 1 from table where condition is the cheapest way.
This means that You want a value "1" as output or Most of the time used as Inner Queries because for some reason you want to calculate the outer queries based on the result of inner queries.. not all the time you use 1 but you have some specific values...
This will statically gives you output as value 1.
I see it is always used in SQL injection,such as:
www.urlxxxxx.com/xxxx.asp?id=99 union select 1,2,3,4,5,6,7,8,9 from database;
These numbers can be used to guess where the database exists and guess the column name of the database you specified.And the values of the tables.
it simple means that you are retrieving the number first column from table ,,,,means
select Emply_num,Empl_no From Employees ;
here you are using select 1 from Employees;
that means you are retrieving the Emply_num column.
Thanks
The reason is another one, at least for MySQL. This is from the MySQL manual
InnoDB computes index cardinality values for a table the first time that table is accessed after startup, instead of storing such values in the table. This step can take significant time on systems that partition the data into many tables. Since this overhead only applies to the initial table open operation, to “warm up” a table for later use, access it immediately after startup by issuing a statement such as SELECT 1 FROM tbl_name LIMIT 1
This is just used for convenience with IF EXISTS(). Otherwise you can go with
select * from [table_name]
Image In the case of 'IF EXISTS', we just need know that any row with specified condition exists or not doesn't matter what is content of row.
select 1 from Users
above example code, returns no. of rows equals to no. of users with 1 in single column