I took over managing an internal website for the company that I'm working for and I need to get data out of a mysql database. The problem that I'm encountering is that the data is in 6 different tables, all with the same fields but the rows are all unique (the row starts in one table and then gets completely moved to a different table after it is processed by an employee).
Is there an easy way to query against all 6 at once? It would also be useful to be able to retrieve the title of the table it came from.
I'm using PHP to run the query and display it. Would it be better to create another table that defines where all the rows are, have a unique id and then another field for which table it's in?
To complete this query, use union all:
select
'Table1' as TableName,
*
from
Table1
union all
select
'Table2',
*
from
Table2
union all
select
'Table3',
*
from
Table3
...and so on
For better database design, you would want to either have one table with all the rows in it, and a designated Status table where you can link a StatusID column to that says what status that given row is in. A table for each stage in a process is a poor design and will only lead to massive headaches down the road.
If you can't reorganize the tables so that you have just one with all rows and a marker for where in the process they are, I would go for a UNION-approach. Ie:
SELECT 'Data from Table 1', t1.field1, ...
FROM Table1 t1
UNION
SELECT 'Data from Table 2', t2.field1, ...
FROM Table2 t2
UNION
(Table3, 4, 5 and 6 in the same manner)
....
That way you can see where the data is originating from and you get all 6 at once. Just remember that you have to have the exact same field list in all parts of the UNION.
You could create a code generator that generates SQL statements to query the 6 tables. The generator would create a UNION of 6 selects and add a "table" column to each select with a constant value equal to the name of the table queried. That would make writing the statements easy, though I wouldn't say that writing the generator would be.
Related
i have multiple table that join together and i need one query and get all references too ! is that possible in yii2??
get them in hierarchy array ??
How ???
Is it possible to do not use join???
thanks for your help!!!!
If you created the model classes for each table using Gii and selected to create the relations in the generated models, you can do something like the following.
1) In your Countries model just change the method that declares the relationship with Airports like this:
public function getAirports() {
return $this->hasMany(Airports::className(), ['country_id' => 'id'])->with('airlines');
}
2) When you do the query for the countries and you need to have the related airports, airlines and flightbooked do it like this:
$countries = Countries::find()
->where('something = something_else')
->with('airports')
->with('flightbooked')
->all();
This way you will get all the related models populated with way less queries to the database than using lazy-loading.
I just wanted to give a small suggestion:
As you are maintaining the relations in the tables and if you have generated your code using Gii, then that will generate the joins for you. You can then access any column of any table easily.
But I think UNION may not be an alternative to JOIN.
Maybe u can use union all for this. with this operator, you can concatenate the result sets from multiple queries together, preserving all of the rows from each. Note that a UNION operator (without the ALL keyword) will eliminate any "duplicate" rows which exist in the resultset. The UNION ALL operator preserves all of the rows from each query (and will likely perform better since it doesn't have the overhead of performing the duplicate check and removal operation).
The number of columns and data type of each column must match in each of the queries. If one of the queries has more columns than the other, we sometimes include dummy expressions in the other query to make the columns and datatypes "match". Often, it's helpful to include an expression (an extra column) in the SELECT list of each query that returns a literal, to reveal which of the queries was the "source" of the row.
SELECT 'col1' AS source, col23, col343, col33, d FROM table1 WHERE ...
UNION ALL
SELECT 'col2', t2.fee, table2.fi, table2.fo, 'fum' FROM table2 JOIN table3 ON ...
UNION ALL
SELECT 'col3', '1', '2', buckle, my_shoe FROM table4
You can wrap a query like this in a set of parenthesis, and use it as an inline view (or "derived table", in MySQL lingo), so that you can perform aggregate operations on all of the rows. e.g:
select one.a
, SUM(one.b)
FROM (
SELECT 'q1' AS source, a, b, c, d FROM t1
UNION ALL
SELECT 'q2', t2.fee, t2.fi, t2.fo, 'fum' FROM t2
) one
GROUP BY one.a
ORDER BY one.a
But i think joining tables more suitable. Hope help you
I have a few tables with the same structure built and wanted to query them at once using PHP MYSQL.
The challenging part that I face was to query x tables where I do not know how many of them there. (Assuming user will select the tables on UI perspective). The reason of this is to output them into a csv format.
For example:-
Date, xTable, yTable, zTable, ....
==============================b
bla 1 2 3
bla 4 3 5
...
...
How can I modify below query to cater for above needs? (The query needs to be flexible enough to query multi table).
SELECT created_dt,
xTable FROM needToQueryMultiTable WHERE created_dt BETWEEN ? AND ?
You can create a view of all possible tables:
create v_tables as
select 'table1' as which, t.*
from table1 t
union all
select 'table2' as which, t.*
from table2 t
. . .;
Then, you can select from the view.
In MySQL this is not particularly efficient, because all the tables will still need to be read. However, for smaller tables this could be a reasonable solution.
You should ask yourself why you have identically structured tables in the databases. In general, these should be combined into a single table. For performance, you can partition the table.
We have records with a count field on an unique id.
The columns are:
mainId = unique
mainIdCount = 1320 (this 'views' field gets a + 1 when the page is visited)
How can you insert all these mainIdCount's as seperate records in another table IN ANOTHER DBASE in one query?
Yes, I do mean 1320 times an insert with the same mainId! :-)
We actually have records that go over 10,000 times an id. It just has to be like this.
This is a weird one, but we do need the copies of all these (just) counts like this.
The most straightforward way to this is with a JOIN operation between your table, and another row source that provides a set of integers. We'd match each row from our original table to as many rows from the set of integer as needed to satisfy the desired result.
As a brief example of the pattern:
INSERT INTO newtable (mainId,n)
SELECT t.mainId
, r.n
FROM mytable t
JOIN ( SELECT 1 AS n
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
) r
WHERE r.n <= t.mainIdCount
If mytable contains row mainId=5 mainIdCount=4, we'd get back rows (5,1),(5,2),(5,3),(5,4)
Obviously, the rowsource r needs to be of sufficient size. The inline view I've demonstrated here would return a maximum of five rows. For larger sets, it would be beneficial to use a table rather than an inline view.
This leads to the followup question, "How do I generate a set of integers in MySQL",
e.g. Generating a range of numbers in MySQL
And getting that done is a bit tedious. We're looking forward to an eventual feature in MySQL that will make it much easier to return a bounded set of integer values; until then, having a pre-populated table is the most efficient approach.
I have 2 tables. suppose a & b
a has id, name, roll. b has id,group,name
This name column data are not same. How can I select and uniquely identify them?
I know about
SELECT a.id,a.name,a.group FROM a,b ............
I know this. But this is an example. I am working with huge amount of data with 20-30 columns in each table. So I don't want to write the column names I need to select rather I want to write the names that I want to exclude.
Like
SELECT * Except b.name............
OR is there any way to uniquely identify after join. Like
.......... a,b WHERE a.name as name1
Please don't ask why those column names are same. I admit it was a mistake. But it's already implemented and heavily used. So finding another way. Is there any simple way to exclude a column while merging them?
Well, you can't write the names you wish to exclude. That is not how SQL works.
However, if writing out 20-30 column names is that much of a burden, you can use information_schema.columns. I write it that way, because 20-30 column names is not particularly large and writing them out is probably less effort than writing the question.
But, back to the solution. It looks something like this:
select concat(c.column_name, ' as ', 'a_', column_name, ', ')
from information_schema.columns c
where table_name = 'a' ;
You might want to include the table schema as well.
As an IDEA, what you can do is, if you want to avoid columns of specific table & your statements have multiple table, you can try following,
Suppose you have 20 columns in table a & 5 columns in table b, you want to avoid col2,col3 & col4 of table b. Standard method is that you should write name of all columns of table a & required columns of table b. But you can avoid to write long list of 20 columns of table by writing a.* & then type required columns of table b. Please see below statement.
Select a.*,b.col1,b.col4,b.col5 from a,b
But if you require to exclude some columns from both table, then I think there is no other way than writing all required column names from both table.
There is no way to exclude a column in SQL SELECT Statement, you can only select a column. You can give alias name to columns while selecting them like below, so that you can identity columns using those alias names.
SELECT a.id as [column1],a.name as [column2],a.group as [column3] FROM a,b ............
There is no way to exclude a specific column but you can avoid to write all columns name and easy your job by below steps-
Step1: Execute below query-
SELECT a.*,b.* FROM a,b ............limit 1;
Step2: Export it into csv format with headings.
Step3: Copyp first (heading) row from csv.
Step4: Delete columns, those are not required and use other columns in your query.
There's only one waY i could see-
first create a temorary table
CREATE TEMPORARY TABLE IF NOT EXISTS mytable
(id int(11) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM;
then put your column in temporary table-
SELECT * INTO mytable
FROM YourTable
/* Drop the cloumns that are not needed */
ALTER TABLE mytable
DROP COLUMN ColumnToDrop
/* Get results and drop temp table */
SELECT * FROM #TempTable
DROP TABLE #TempTable
If I have two tables in a MySQL database that both have a column called order_number, given an order_number value but not knowing which table it comes from how would I go about setting up a query that would return the name of the table it was found in?
I am particularly interested in the name of the table so I can set up subsequent updates to that table.
Also, I am using PHP for the handling of the query.
select "tableA" as tableName,order_number from tableA where order_number=5
UNION
select "tableB" as tableName,order_number from tableB where order_number=5;