Nested queries to different databases - mysql

I'm trying to use INFORMATION_SCHEMA, because I think it will help a lot on what i want to do. I tried to find the right query, but none of them worked. The common thing in all queries was that I used nested queries on different databases. The last one I used was this one below.
SELECT table_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE column_name='field1'
AND table_schema='database1'
AND (SELECT * FROM database1.table_name WHERE field1 > somevalue ) IS
NOT NULL
But this returned error
#1146 - Table 'database1.table_name' doesn't exist.
Is this because i'm using two nested queries each to a different database? Is there a way I can make this work?
What I want to do is a list of the table names of a database which have field1 in their field list and at least one of the values of field1 is greater than somevalue.
I use MySQL v5.5

I'd advice you to use a join other than a nested query

Related

Query on the tables name list

I want to select the nth element of the table list provided by the SHOW TABLES query.
If I use the following code to list them alphabetically:
WITH tableslist as (SHOW TABLES)
SELECT Tables_in_DBname FROM tableslist ORDER BY Tables_in_DBname
I get an error regarding the syntax near 'SHOW TABLES).
If I only do the SHOW TABLES query I get a table with the column Tables_in_DBname.
The main goal of this would be to populate a checkbox in VBA with the table names in the database, so in case I am looking in the completely wrong direction to go about this please correct me.
I am able to populate the cbo with the fields of specific tables, but I could not find a way to list the tables from the database as fields, so I am attempting to make an ordered list to select the nth element from.
The server type is MariaDB.
You can use information_schema.tables to get the list of tables:
SELECT table_name FROM information_schema.tables
WHERE table_schema = '<name of database>' ORDER BY table_name;
This allows you to build more complex queries that inspect the tables in the database.

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.

select all from one table but compare to multiple tables

Hello I have the following query:
SELECT *
FROM ams.TestResultHiPot_Archive,ams.unit u
WHERE timestamp >='3/16/2017 20:39 ' AND timestamp <= '3/17/2017, 20:39' AND LOWER(line_code)=LOWER('aac04')
AND LOWER(unitmodelnumber) like LOWER('%%%') AND unitmodelnumber != 'VTI' and u.serial_num=unitserialnumber and u.date_deleted is null
this table has many fields so I want to stay away from hard coding each field AND also this structure works for multiple tables.
The only issue I am having is some of the comparison items are in the units table so I want to visit that tablet to compare and if it matches then include that record in my result from the ORIGINALTEST RESULTS ARCHIVE table NOT the units table.
the main issue I am seeing is that the select * is causing both tables to return all of their fields.
Is there a way to use select * ,and still compare 2 tables but get the columns ONLY from one table ?
I have tried right join, left join, inner join but nothing seems to work, they all return all the columns from both tables, maybe I have done it incorrectly, or maybe this can't be done?
I also thought maybe doing like a query that selects all the table fields and then storing them in an array and passing that array as my select parameters, that way I am passing the exact needed parameters without hardcoding (since I would always consult the table) but that seems like it would take longer since pgsql is slower. Any suggestions are greatly appreciated.
select ams.TestResultHiPot_Archive.*

WHERE IN with subquery NOT WORKING as expected

I am trying to get result from my categories table using the parent path i have created.
When i launch the request WHERE IN with manual data it's working perfectly.
When i am trying the same request dynamically with subquery, i got only one result instead of 4 expected.
I do not understand why, can you help me ?
http://sqlfiddle.com/#!2/88b68/6
/*Working query*/
SELECT t.id_categorie FROM t
WHERE t.id_categorie IN (1396,1399,1403,1412)
/*Not working by subquery ??*/
SELECT cat.id_categorie FROM t as cat
WHERE
cat.id_categorie IN (SELECT REPLACE(t.path,'.',',') FROM t WHERE t.id_categorie = 1412)
Thanks by advance,
Regards,
Using in with a comma delimited list does not do what you want. Even when you use a subquery. You could try this:
SELECT cat.id_categorie
FROM t cat
WHERE EXISTS (SELECT 1
FROM t
WHERE t.id_categorie = 1412 AND
find_in_set(cat.id_categorie, REPLACE(t.path, '.', ',')) > 0
);
I'm not sure what your data looks like or even what this query is supposed to be doing (it seems strange that the subquery is on the same table as the outer query). Usually, though, you want to store things in tables rather than delimited lists. You see, SQL has a built-in data structure for lists. It is called a table.
The reason this does not work is that your inner SELECT produces a single comma-separated VARCHAR, rather than four individual integers.
In MySQL you can use find_in_set, like this:
SELECT cat.id_categorie FROM t as cat
WHERE find_in_set(cat.id_categorie, (
SELECT REPLACE(t.path,'.',',')
FROM t WHERE t.id_categorie = 1412))
What I did was replacing the IN expression in your query with a call to find_in_set, leaving everything else the same.
Demo
However, this solution is fundamentally flawed, because it stores multiple values in a single column to represent a many-to-many relationship. A better approach to implementing this requirement is using a separate table that connects rows of the table to their related rows.

Subquery for fetching table name

I have a query like this :
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo WHERE group='BEST'
Basically, the table name for the main query is fetched through the subquery.
I get an error that #1054 - Unknown column 'group' in 'where clause'
When I investigate (removing the where clause), I find that the query only returns the subquery result at all times.
Subquery table adm_linkedfields has structure id | name | linktable
Currently am using MySQL with PDO but the query should be compatible with major DBs (viz. Oracle, MSSQL, PgSQL and MySQL)
Update:
The subquery should return the name of the table for the main query. In this case it will return tbl_company
The table tbl_company for the main query has this structure :
id | name | group
Thanks in advance.
Dynamic SQL doesn't work like that, what you created is an inline-view, read up on that. What's more, you can't create a dynamic sql query that will work on every db. If you have a limited number of linktables you could try using left-joins or unions to select from all tables but if you don't have a good reason you don't want that.
Just select the tablename in one query and then make another one to access the right table (by creating the query string in php).
Here is an issue:
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo
WHERE group='BEST';
You are selecting from DT which contains only one column "linktable", then you cant put any other column in where clause of outer block. Think in terms of blocks the outer select is refering a DT which contains only one column.
Your problem is similar when you try to do:
create table t1(x1 int);
select * from t1 where z1 = 7; //error
Your query is:
SELECT *
FROM (SELECT linktable
FROM adm_linkedfields
WHERE name = 'company'
) cbo
WHERE group='BEST'
First, if you are interested in cross-database compatibility, do not name columns or tables after SQL reserved words. group is a really, really bad name for a column.
Second, the from clause is returning a table containing a list of names (of tables, but that is irrelevant). There is no column called group, so that is the problem you are having.
What can you do to fix this? A naive solution would be to run the subquery, run it, and use the resulting table name in a dynamic statement to execute the query you want.
The fundamental problem is your data structure. Having multiple tables with the same structure is generally a sign of a bad design. You basically have two choices.
One. If you have control over the database structure, put all the data in a single table, linktable for instance. This would have the information for all companies, and a column for group (or whatever you rename it). This solution is compatible across all databases. If you have lots and lots of data in the tables (think tens of millions of rows), then you might think about partitioning the data for performance reasons.
Two. If you don't have control over the data, create a view that concatenates all the tables together. Something like:
create view vw_linktable as
select 'table1' as which, t.* from table1 t union all
select 'table2', t.* from table2 t
This is also compatible across all databases.