查询以选择具有相似列值的表

时间:2010-09-24 07:36:52

标签: sql

继续我的主题“http://stackoverflow.com/questions/3767000/invalid-column-name-though-its-there”

我想写一个查询,选择具有EntityId和DataclassId列值的表作为相同的值(当然跳过空值)

以下是我的数据库

的示例
Table_1
ID  Sequence    Type    Heigh  Weight   EntityId    DataclassId
0   1           s       1.4     2.5     42-2c-Qi    42-2c-Qi
1   2           s       2.4     2.5     zh-km-xd    zh-km-xd
2   3           s       3.4     2.5     8n-tr-l7    8n-tr-l7

Table_2
ID  Data    Person    EntityId    DataclassId
0   1        Dave     58-zj-4o    41-2c-Q7
1   2        Sara     99-op-t6    oy-7j-mf
2   3        Silve    75-qy-47    2d-74-ds

Table_3
ID  Name    Genre   EntityId    DataclassId
0   LR      Ac      78-jd-o9    78-jd-o9
1   OI      Dr      4t-jb-qj    4t-jb-qj
2   DH      Do      7j-3e-ol    7j-3e-ol

Table_4
ID     Name    EntityId    DataclassId
NULL   NULL     NULL        NULL   
NULL   NULL     NULL        NULL   

Table_5
ID  Data    Person    EntityId    DataclassId
0   1        Dave     58-zj-4o    41-2c-Q7
1   2        Sara     99-op-t6    oy-7j-mf
2   3        Silve    fg-se-pl    2d-74-ds

输出应为

Table_1
Table_3

修改

我也使用c#代码遍历数据库的表。但我还没有得到正确的结果。我需要的是对rootQ变量的正确查询。

    public void getRootTables_checkSP()
    {
        string connect = "Data Source= EUADEVS06\\SS2008;Initial Catalog=TacOps_4_0_0_4_test;integrated security=SSPI; persist security info=False;Trusted_Connection=Yes";
        //Query to Select all Tables that have  
        //EntityId and DataclassId columns in them
        string query =
            "SELECT tabs.name " +
            "FROM sys.tables tabs INNER JOIN sys.columns cols " +
            "ON tabs.object_id = cols.object_id " +
            "AND cols.name IN ('EntityId', 'DataclassId')";

        int i = 0;
        int j = 0;  //Count for Root Tables
        SqlDataReader tables_list = null;
        SqlDataReader rootTables_list = null;
        SqlConnection conn = new SqlConnection(connect);
        SqlConnection conn2 = new SqlConnection(connect);
        try
        {
            //Write all table that have EntityId and
            //DataclassId cols into tables_list
            conn.Open();
            SqlCommand cmd_1 = new SqlCommand(query, conn);
            tables_list = cmd_1.ExecuteReader();

            while (tables_list.Read())
            {
                //Query to select Root Tables
                //EntityId and DataclassId values are identical in Root Tables
                //HERE IS WHERE I GOT STUCK AND COULDN'T FIGURE OUT THE CORRECT QUERY
                string rootQ =
                    "SELECT * " +
                    "FROM " + tables_list[0] + " " +
                    "WHERE EntityId not NULL " +
                    " AND DataclassId not NULL " +
                    " AND EntityId != DataclassId";
                try
                {
                    //Write Root Tables into rootTables_list
                    conn2.Open();
                    SqlCommand cmd_2 = new SqlCommand(rootQ, conn2);
                    rootTables_list = cmd_2.ExecuteReader();

                    //Loop through the rootTables_list and print out the values
                    while (rootTables_list.Read())
                    {
                        string s = rootTables_list[0].ToString();
                        Console.WriteLine(s);
                        j++;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex);
                }
                finally
                {
                    Console.WriteLine();
                    Console.WriteLine("{0} Root Tables-Count ", j);
                    Console.WriteLine();
                    conn2.Close();
                }
                i++;
            }

        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e);
        }
        finally
        {
            Console.WriteLine();
            Console.WriteLine("{0} All Tables-Count ", i);
            Console.WriteLine();
            conn.Close();
        }

    }

3 个答案:

答案 0 :(得分:0)

使用SQL和代码的组合而不是大量查询可能最容易做到这一点。

如果我这样做,我会创建一个查找和查找不符合表格的行的查询:


SELECT * FROM tablx
WHERE EntityId not NULL
 AND DataclassId not NULL
 AND EntityId != DataclassId;

如果它返回任何行,那么该表就不存在了。

依次在每个表上使用此查询。如果返回任何行,那就没有好处;丢弃它。如果未返回任何行,请将名称保存在列表中。

完成后,您将获得所有有效表的列表。

答案 1 :(得分:0)

使用游标的整个逻辑 - 无法想到在DB中直接执行任何其他方式。 为简洁起见,我只是在光标中打印表名。您可以在那里进行任何处理,包括将它们保存在表格中以供将来使用

DECLARE @tableName nvarchar(500);
DECLARE @dynamicQuery nvarchar(600);

DECLARE candidateTables_cursor CURSOR FOR 
SELECT tabs.name  
FROM sys.tables tabs INNER JOIN sys.columns cols 
ON tabs.object_id = cols.object_id 
AND cols.name IN ('EntityId', 'DataClassId')
OPEN candidateTables_cursor;

FETCH NEXT FROM candidateTables_cursor INTO @tableName;

WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE @count int;
    DECLARE @ParmDefinition NVARCHAR(500);

    SET @dynamicQuery = N'SELECT @countOUT = COUNT(1) FROM ' + @tableName + ' WHERE EntityId = DataclassId'

    SET @ParmDefinition = N'@countOUT int OUTPUT'

    sp_executeSQL(@dynamicQuery , @ParmDefinition , @countOUT=@count OUTPUT)

    if @count > 0
       PRINT @tableName 

FETCH NEXT FROM candidateTables_cursor INTO @tableName;
END

CLOSE candidateTables_cursor;
DEALLOCATE candidateTables_cursor;

答案 2 :(得分:0)

UNION ALL就足够了。

SELECT TOP 1 'Table1' FROM Table1 WHERE EntityID = DataClassID
UNION ALL SELECT TOP 1 'Table2' FROM Table2 WHERE EntityID = DataClassID
UNION ALL SELECT TOP 1 'Table3' FROM Table3 WHERE EntityID = DataClassID
UNION ALL SELECT TOP 1 'Table4' FROM Table4 WHERE EntityID = DataClassID