Check what table a record belongs in using MySQL - 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).

Related

use column names from inner query select the columns to display in outer query

My scenario is as follows( in MySQL)
I have a table say table 1, which has 2 columns:
userID, column_acess
Table 2 which has a list of columns say col1,col2,col3, etc.
Now What I would like to do is use pymySQL to query table 1 for the columns a particular userID is allowed to acesss, by inspecting the column, acess field ( which will contain a comma seperated list of columns in tabl2), and use that result in another sql query ( which works on table2) to actually get the data from the respective columns a user is allowed to acess.
So essentially I would like something like:
Select (Select column_acess from tabl1 where user_ID='123') from table2
So inner query should return the list of columns say col1, col2, which would be used to select the columns in the outer query in table2
How do I do that in mySQL?
I strongly encourage you too read this post. You should either first store columns in variable or use dynamic sql query. Use SELECT result as COLUMN name in other SELECT
BTW your schema is not even in 1 NF since you don’t have atomic values in table 1. You should avoid that.
MySQL supports the granting of column-level privileges to users, using the standard grant statement.
I would suggest that you start with the documentation on this subject.
An alternative to using grant for columns is to create views for different user types. This is, in fact, the more general solution, because the views can filter rows as well as columns. The idea is that the underlying tables are not directly accessible. The views are, so all access needs to go through the views.

Mysql, EXIST / NOT EXIST, asterisk as column name

An example from a book about MySql:
SELECT vendor_id, vendor_name, vendor_state
FROM vendors
WHERE NOT EXISTS
(SELECT *
FROM invoices
WHERE vendor_id = vendors.vendor_id)
"In this example, the correlated subquery selects all invoices that have the same vendor_id value as the current vendor in the outer query. Because the subquery doesn't actually return a result set, it doesn't matter what columns are included in the SELECT clause. As a result it's customary to just code an asterisk."
The invoices table has like 10 separate columns which look like this: http://prntscr.com/h3106k
I am not fully understanding the asterisk part. Since there is 10 separate columns in this table is it not possible that some columns will be empty (or not empty) and we can check for that? There is no use of checking individual columns, and it only makes sense to check a table as a whole (so nothing else that the asterisk is needed here)?
In this example, there is no row satisfying the condition (WHERE …=…). So, it is not important which column is checked as there is no row to check at all.
An alternative would be the following clause, maybe it is easier to understand:
SELECT vendor_id, vendor_name, vendor_state
FROM vendors
WHERE
(
SELECT COUNT(vendor_id)
FROM invoices
WHERE vendor_id = vendors.vendor_id
) = 0

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

Search SQL query from multiple tables MySQL

I am trying to perform search on multiple tables.
I will simplify problem and say that I have 2 tables Worker and Customer both have Id, Name, Surname and Worker has additional Position, all fields are varchar except Id which is Int.
How to make a query that will return rows of either Customer or Worker, where one of theirs fields contains entered search string.
I have tried with joins but I got returned joined row also.
select id,name,surname,position,'worker' as tbl from worker where ..
union all
select id,name,surname,'','customer' from customer where ...
In this way you can even know results what table belong to.
Just UNION both queries.
If you really can JOIN those two, you can use
an IF statement in the SELECT clause to show the right field.
But, from what I understand from your question, go with UNION