简体   繁体   中英

Compare one table with all tables in database

This is sample table data. My Database consists of so many tables like this. In all the tables where wv1 is same and rv1 is different

wv1           rv1
341.6         2.48
343.6         2.58
344.7         2.37
346.3         2.32
347.9         2.29
349.5         2.36
351.1         2.23
352.6         2.24
354.2         2.25
355.8         2.29
357.4         2.28
358.9         2.23

For comparing one table with another table, I mentioned another table rv1 as rv2 here. I am using the data rv1 from user selected tablename, and rv2 for all the tables in the database The formula is

  • I = ACOS[rv1.rv2/|rv1|.|rv2|]

PostgreSQL Query for comparing two tables is shown below, I want to compare one table with all the tables in the database and produce i value for each comparison.

select
    acos(sum(t1.rv1 * t2.rv2) / (
        sqrt(sum(power(t1.rv1, 2))) * sqrt(sum(power(t2.rv2, 2)))
    )) as i
from
    t1
    inner join
    t2 on t1.wv1 = t2.wv2

This query is joining two tables and applying formula described above, then it shows correct output . Now I want to compare single table(t1 as user defined table, t2 as all the tables in the database) with all the tables in the database and generate I value for each comparison. I want to apply formula for all the tables in the database.

The output should be like this

Final Output

   Ivalue
   0.3559772512926 
   0.52684312
   .............
   .............

I want to write the formula in PostgreSQL query, How to write it. .

However you look at it, it comes down to several selects, one per table, which you can combine with UNION ALL:

select acos(...
from t1 inner join t2 on t1.wv1 = t2.wv2
UNION ALL
select acos(...
from t1 inner join t3 on t1.wv1 = t3.wv3
UNION ALL
...

If I understand this correctly, you actually want to compare different sets that all 'look alike' (that is 2 columns, same number of rows, identical wv1 values) and each set is stored in a new table, right ?

My first remark would be: why didn't you store all the sets in the same table and add an extra column (eg. set_id) that points to which set the value-pair belongs. If that would have been the case you could have created a query like this:

select t1.set_id as left_set_id,
       t2.set_id as right_set_id,
       acos(sum(t1.rv1 * t2.rv2) / ( sqrt(sum(power(t1.rv1, 2))) * sqrt(sum(power(t2.rv2, 2))))) as i
from bigtable as t1
inner join bigtable as t2 
        on t1.wv1 = t2.wv2
       AND t1.set_id > t2.set_id
GROUP BY t1.set_id,
         t2.set_id
ORDER BY t1.set_id,
         t2.set_id

Note: the t1.set_id > t2.set_id avoids that you compare a set with itself + it seems (to me) that the relationship is symmetrical anyway so you only need to compare sets in one direction.

Update, if you want to compare just 1 set with all the other sets, you'll have to use it like this :

select t2.set_id,
       acos(sum(t1.rv1 * t2.rv2) / ( sqrt(sum(power(t1.rv1, 2))) * sqrt(sum(power(t2.rv2, 2))))) as i
from bigtable as t1
inner join bigtable as t2 
        on t1.wv1 = t2.wv2
       AND t1.set_id <> t2.set_id
WHERE t1.set_id = '<base set identifier>'
GROUP BY t2.set_id
ORDER BY t2.set_id

Now, since we don't have this, we'll have to fake it. To do so I would suggest to create a view that UNION ALL s all your tables and then you can run the query above on the view instead of on bigtable

CREATE VIEW bigview
AS 
SELECT 'table1' as set_id, wv1, rv1 FROM table1
UNION ALL
SELECT 'table2' as set_id, wv1, rv1 FROM table2
UNION ALL
SELECT 'table3' as set_id, wv1, rv1 FROM table3
UNION ALL
etc...

This view can then be re-used regardless for which set (= table) you are comparing, you will have to make sure though that it includes all the tables (= sets) you want to be included in the comparison.

PS: you might have to work a bit on the syntax, don't have PostgreSQL available right here. PS: the documentation mentions you can use @ to calculate the absolute value of a number; I'm guessing that would be easier than taking the root of the square. It surely will be less prone to overflows.

It is made through JSP + PostgreSQL

String ss1 = "SELECT UPPER(table_name)FROM information_schema.tables where table_schema='public' and table_type='BASE TABLE' ORDER BY table_name ASC;";
stmt = connection.createStatement();
rset=stmt.executeQuery(ss1);

The String ss1 is passed as dbTab

String usTab ="oak";          
while (rset.next()) {
String sname1 = rset.getString(1);
String dbTab = sname1.toUpperCase(); 
try
{
out.println("<tr><td>"  + dbTab + "</td><td>"+ usTab + " vs " + dbTab + "</td>");
if(dbTab.equals(usTab)) continue;
Connection connection = DriverManager.getConnection(ss, "postgres", "acheive9");
String ss2 = "select acos(sum("+usTab+".reflectance * "+dbTab+".reflectance) / ( sqrt(sum(power("+usTab+".reflectance, 2))) * sqrt(sum(power("+dbTab+".reflectance, 2))))) as i from "+usTab+" inner join "+dbTab+" on "+usTab+".wavelength = "+dbTab+".wavelength";
stmt2 = connection.createStatement();
rset2=stmt2.executeQuery(ss2);
while (rset2.next()) {
String sname17 = rset2.getString(1);
out.println("<td>"+sname17+"</td></tr>");
}

This Code is working..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM