Related
I am getting data from a linked server, in which lets say I am having an identifier which I am joining with the identifier on my server and getting the data for it.
But the thing is identifier from Linked server contains some extra characters and while joining its not able to correctly join.
Can i do something like this that when I join, I will replace the identifies extra characters with space or NULL.
For ex.
Table 1
Col1 Col2
23rf name
24rf id
Table 2
Col1 Col2
23 name1
24 id1
SELECT
ta1.*,
ta2.*
FROM Table1 ta1
INNER JOIN Table2 ta2
ON ta1.Col1 = ta2.Col2
So this will give NULL
I want a query which can result the data by replacing "rf" to "" and join the two table, so that I can't get a NULL DataSet.
Second Approach:
Can I insert the data from one table to another table where while inserting, I can replace "rf" to "".
But, I do not know how to proceed for the above approach.
Please suggest.
You can do this by assigning an id to each of your tables using ROW_NUMBER. So, I used now row as their common field. See and try my queries below:
In SQL-SERVER:
SELECT ta1.Col1,ta1.Col2,ta2.Col1,ta2.Col2 FROM
(SELECT
ROW_NUMBER() OVER(ORDER BY Col1) AS Row,*
FROM Table1) AS ta1
INNER JOIN
(SELECT
ROW_NUMBER() OVER(ORDER BY Col1) AS Row,*
FROM Table2) AS ta2
ON ta1.Row=ta2.Row
In MYSQL:
SELECT ta1.Col1,ta1.Col2,ta2.Col1,ta2.Col2 FROM
(SELECT
#row_number1:=#row_number1+1 AS RowNumber1,
Col1,
Col2
FROM Table1, (SELECT #row_number1:=0)AS x ORDER BY Col1) AS ta1
INNER JOIN
(SELECT
#row_number2:=#row_number2+1 AS RowNumber2,
Col1,
Col2
FROM Table2, (SELECT #row_number2:=0)AS y ORDER BY Col1) AS ta2
ON ta1.RowNumber1=ta2.RowNumber2
I am trying to get sum for some columns from across multiple mysql tables using python/sqlalchemy. The number of tables is dynamic, and each table has same schema.
Table_1
| col1 | col2| ... |
Table_2
| col1 | col2| ... |
Table_...
| col1 | col2| ... |
I studied sqlachemy, and realised that the better idea might be to generate a SQL text and execute it, creating models might not be a good solution, I feel that may introduce additional cost on performance, I prefer a single SQL statement.
select (t1.col1 + t2.col1 + t3.col1 + t?.col1 ...) as col1, (t1.col2 + t2.col2 + ...) as col2,
... from
(select sum(col1), sum(col2), sum(col3) ... from Table_1 as t1,
select sum(col1), sum(col2), sum(col3) ... from Table_2 as t2,
...
)
The above is the SQL I intend to make using python. I am not a SQL professional, so I am not sure if that is a good statement, and I am wondering if there are any better solution, simpler and efficient, other than this?
Your general approach looks reasonable. Getting the SUMs from the individual tables as a single row, and the combining those, is the most efficient approach. There's just a couple of minor fixes.
It looks like you will need to provide an alias for each of the SUM() expression returned.
And you're going to need to wrap the SELECT from each table in a set of parens, and give each of those inline views an alias.
Also, there's a potential for one of the inner SUM() expressions to return a NULL, so the addition performed in the outer query could return a NULL. One fix for that would be wrap the inner SUM expressions in a IFNULL or COALESCE, to replace a NULL with a zero, but that could introduces a zero where the outer SUM would really be a NULL.
Personally, I'd avoid using the comma notation for the JOIN operation. The comma is valid, but I'd write it out using the CROSS JOIN keywords, to make it a little more readable.
But my preference would be avoid the JOIN and the addition operations in the outer query. I'd use a SUM aggregate in the outer query, something like this:
SELECT SUM(t.col1_tot) AS col1_tot
, SUM(t.col2_tot) AS col2_tot
, SUM(t.col3_tot) AS col3_tot
FROM ( SELECT SUM(col1) AS col1_tot
, SUM(col2) AS col2_tot
, SUM(col3) AS col3_tot
FROM table1
UNION ALL
SELECT SUM(col1) AS col1_tot
, SUM(col2) AS col2_tot
, SUM(col3) AS col3_tot
FROM table2
UNION ALL
SELECT SUM(col1) AS col1_tot
, SUM(col2) AS col2_tot
, SUM(col3) AS col3_tot
FROM table3
) t
That avoids anomalies with NULL values, and makes it return the same values that would be returned if the the individual tables were all concatenated together. But this isn't any more efficient than what you have.
To use the JOIN method, as in your query (if I don't mind returning a zero where a NULL would have been returned in the query above, to that approach to work:
SELECT t1.col1_tot + t2.col1_tot + t3.col1_tot AS col1_tot
, t1.col2_tot + t2.col2_tot + t3.col2_tot AS col2_tot
, t1.col3_tot + t2.col3_tot + t3.col3_tot AS col3_tot
FROM ( SELECT IFNULL(SUM(col1),0) AS col1_tot
, IFNULL(SUM(col2),0) AS col2_tot
, IFNULL(SUM(col3),0) AS col3_tot
FROM table1
) t1
CROSS
JOIN ( SELECT IFNULL(SUM(col1),0) AS col1_tot
, IFNULL(SUM(col2),0) AS col2_tot
, IFNULL(SUM(col3),0) AS col3_tot
FROM table2
) t2
CROSS
JOIN ( SELECT IFNULL(SUM(col1),0) AS col1_tot
, IFNULL(SUM(col2),0) AS col2_tot
, IFNULL(SUM(col3),0) AS col3_tot
) t3
But, again, my personal preference would be to avoid doing those addition operations in the outer query. I'd use the SUM aggregate, and UNION the results from the individual tables, rather than doing a join.
Unless you have some where clauses to join those tables together, you're going to end up with a cartesian join, where every record from each table in the query is joined against all other combinations of records from the other tables. so if each of those tables has (say) 1000 records, and you've got 5 tables in the query, you're going to end up with 1000^5 = 1,000,000,000,000,000 records in the result set.
What you want is probably something more like this:
SELECT sum(col1) AS sum1, sum(col2) AS sum2, ....
FROM (
SELECT col1, col2, col3, ... FROM table1
UNION ALL
SELECT col1, col2, col3, ... FROM table2
UNION ALL
...
) a
The inner UNION join will take all the columns from each of those tables and turn them into a single contiguous result set. The outer query will then take each of those columns and sum up the values.
This may help u,
select SUM(col1),SUM(col2) from
(
select col1,col2 from Table1
union all
select col1,col2 from Table2
union all
select col1,col2 from Table3
)t
I am using this command to find the same values in two tables when the tables have 100-200 records. But When the tables have 100000-20000 records, the sql manager, browsers, shortly the computer is freesing.
Is there any alternative command for this?
SELECT
distinct
names
FROM
table1
WHERE
names in (SELECT names FROM table2)
Try with join
SELECT distinct t1.names
FROM table1 t1
join table2 t2 on t2.names = t1.names
Use EXISTS:
SELECT distinct t1.names
FROM Table1 t1
WHERE EXISTS(
SELECT 1 FROM tabl2 t2 WHERE t2.names=t1.names
)
SELECT DISTINCT t1.names
FROM table1 t1
INNER JOIN table2 t2 on t1.names=t2.names
The use of the INNER JOIN ensures that there are only exact matches returned from both tables. It should be relatively quick, but indexes may be required over the long term, especially if you're using them for other JOINs and GROUP BYs etc.
a simple join will also do it.
make sure the column is indexed.
select distinct t1.names
from table1 t1, table2 t2
where t1.names = t2.names
Show names from both tables where there is a match
SELECT names
FROM table1
UNION ALL
SELECT names
FROM table2
This query will return duplicated values if there are any. If you only want distinct values then try this but note that there will be an impact on performance
SELECT names
FROM table1
UNION
SELECT names
FROM table2
SELECT table1.names
FROM table1
INNER JOIn table2
ON table1.names = table2.names
Group By table1.names
If I have 2 tables and want to find if they have the same data, what is the most straightforward way to do it in MySQL?
I have read about doing a correlated subquery and UNION ALL but this query is about 2 pages (!) and can not really follow what it is doing. There must be an easier way.
Even if it is e.g. make MySQL copy the table data to files and do a vimdiff (I am not sure that this is even possible -is it?- just thinking out loud).
UPDATE
I am interested only in the table data and not structure. This is to clarify due to an ambiguous comment I made
If you just want to tell whether the tables are identical or not as efficiently as possible, use this query:
SELECT 1 FROM (
SELECT * FROM table1
UNION ALL
SELECT * FROM table2
) t
GROUP BY col1, col2, col3
HAVING count(*) = 1
LIMIT 1
List all the columns in GROUP BY to compare the entire table.
If the result is an empty set, the two tables are identical.
If you want to see the differences, use this query:
SELECT * FROM (
SELECT 'table1' tname, col1, col2, col3 FROM table1
UNION ALL
SELECT 'table2' tname, col1, col2, col3 FROM table2
) t
GROUP BY col1, col2, col3
HAVING count(*) = 1
List the same columns in the inner SELECT as in the GROUP BY, plus a column to distinguish the two tables.
Just throwing this out there, you could emulate a full outer join and then return the rows where just the right or the left side is null.
select t1.*
from table1 t1
LEFT OUTER JOIN table2 t2
ON t1.col1 = t2.col1
AND t1.col2 = t2.col2
AND ...
WHERE t2.id is null
UNION
select t2.*
from table2 t2
LEFT OUTER JOIN table1 t1
ON t2.col1 = t1.col1
AND t2.col2 = t1.col2
AND ...
WHERE t1.id is null
With the FULL OUTER JOIN you can show all rows where the other row is not available in the other table.
Use the following query:
SELECT c1 = cjoin AND c2 = cjoin equiv
FROM (SELECT COUNT(*) c1 FROM Table1) t1,
(SELECT COUNT(*) c2 FROM Table2) t2,
(SELECT COUNT(*) cjoin
FROM Table1 t1
JOIN Table2 t2
ON t1.col1 = t2.col1 AND t1.col2 = t2.col2 AND t1.col3 = t2.col3 ...) tjoin
Assuming the tables have a unique key, this will return equiv = 1 if the tables are equal. It doesn't show the differences, it's just a binary test.
I was reading SQL Cookbook from A.Molinaro, when I came across a solution.
It is based on to tables
emp(empno,ename,job,mgr,hiredate,sal,comm,deptno)
and a view
V
which has the same columns but different rows. The columns mgr and comm might be NULL, other columns not.
The solution in the book is very long and it does not show all differences, although this was the stated problem in 3.7.
I made up my solution which is shorter and shows all differences (means all rows which have different counts in the two tables).
select * from
# those which are contained in the (distinct) union of (col1,col2,...,coln, count) of both tables:
( select empno,ename,job,mgr,hiredate,comm,deptno, count(*) cnt from emp group by empno,ename,job,mgr,hiredate,comm,deptno
union
select empno,ename,job,mgr,hiredate,comm,deptno, count(*) cnt from V group by empno,ename,job,mgr,hiredate,comm,deptno
) as unionOfBoth
where (empno,ename,job,mgr,hiredate,comm,deptno,cnt)
not in
# those which are contained in the intersection of both tables with the equal number of counts:
( select e.empno,e.ename,e.job,e.mgr,e.hiredate,e.comm,e.deptno,e.cnt
from
(select empno, ename,job,mgr,hiredate,comm,deptno, count(*) cnt from emp group by empno,ename,job,mgr,hiredate,comm,deptno) e,
(select empno, ename,job,mgr,hiredate,comm,deptno, count(*) cnt from V group by empno,ename,job,mgr,hiredate,comm,deptno) v
where
e.empno = v.empno
and e.ename = v.ename
and e.job = v.job
and ifnull(e.mgr,0) = ifnull(v.mgr,0)
and e.hiredate = v.mgr
and e.deptno = v.deptno
and ifnull(e.comm,0) = ifnull(v.comm,0)
and e.cnt = v.cnt
);
Basically you count the distinct rows in both tables and do a union (not union all) to get the tmp.table unionBoth. Then you remove those rows, which both tables have in common.
Here two rows r1 from table t1 and r2 from table t2 are considered the same, if
(r1,count of r1 in t1) = (r2, count of r2 in t2), which is equivalent to r1=r2 (on all columns) and (count of r1 in t1) = (count of r2 in t2).
If the tables are small enough, you can export both tables as csv files and then copy one of the tables and paste them side-by-side with the other table. You can just go row by row and see if the outputs are the same that way.
I have two tables Table1 and Table2. There are 10 fields in Table1 and 9 fields in Table2. There is one common column in both the tables i.e. AdateTime. This column saves unix time stamp of user actions. I want to display records from both the tables as a single result but sorting must me according to AdateTime. Recent action should be display first. Sometimes many recent actions in Table1 but few in Table2. Vice versa is also possible. So I want to fetch combine result set from both the tables using single query. I am using PHP MySQL.
Try
SELECT t1.*, t2.*
FROM table1 t1 INNER JOIN table2 t2
ON t1.AdateTime = t2.AdateTime
ORDER BY t1.AdateTime
or (if tables are not related)
SELECT * FROM
(SELECT ADateTime, col1, col2, col3, col4 FROM table1
UNION
SELECT ADateTime, col1, col2, 1 AS col3, NULL AS col4 FROM table2) t2
ORDER by ADateTime
I would use UNION ALL with an inline view. So something like
select col1,col2,col3,col4,col5,col6,col7,col8,col9,AdateTime
from
(
select col1,col2,col3,col4,col5,col6,col7,col8,col9,AdateTime from Table1
UNION ALL
select col1,col2,col3,col4,col5,col6,col7,col8,null as col9,AdateTime from Table2
) t
order by t.Adatetime desc;
yes you can do it. you just need to join these 2 tables with a join condition. when the join condition matches for a row only that row ll be displayed then further you can write the Code for any operation. use order by AdateTime
select t1.column_1234,t2.column_1234
from t1 table1 , t2 table2
where t1.matching_column = t2.matching_column
order by t1.AdateTime;
t1.matching_column And t2.matching_column are the Primary And Foreign keys for these tables (Matching Column)