1

I have a temp table like: #temp321

select * from #temp321

it's return value like

Field1|Field2|Field3|....|FieldN|
--------------------------------
Value1|Value2|Value3|....|ValueN|

This #temp321 table is auto generated from another set of query.So, the number of #temp321 table's column can be vary(1-25). But their will be always a single row. Now i need to write a where statement using those value.
Example :
where Field1='Value1' and Field2='Value2' and Field3='Value3'.....FieldN='ValueN'..(depends on number of column available into the #temp321 table)
How i do it. Thanks in advance

2
  • Since the # of columns can vary, will the other table have as many columns to match, and always in the same order, with the same names?? And will #temp321 only ever have 1 row? Commented Nov 19, 2012 at 11:29
  • yes. the number of column will be same always. please help me to write the where clause only. Commented Nov 19, 2012 at 11:36

1 Answer 1

5

You can do this:

SELECT *
FROM Othertable t1
INNER JOIN #temp321 t2 ON  t1.Field1 = t2.field1 
     AND t1.Field2 = t2.field2 
     AND t1.Field3 = t2.field3;

Update: This what I could do:

JOIN the two tables dynamically instead of the WHERE clause:

DECLARE @DynamicJOINCondition AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);

;WITH cte
AS
(
    SELECT t1.COLUMN_NAME 'T1', t2.COLUMN_NAME 'T2'
    FROM 
    (
       SELECT 
         ordinal_position , 
         column_name
       FROM information_schema.columns 
       WHERE table_name LIKE '#temp321%'
    ) t1
    INNER JOIN
    (
       SELECT 
         ordinal_position , 
         column_name
       FROM information_schema.columns 
       WHERE table_name = 'othertable'
    ) t2 ON t1.ORDINAL_POSITION = t2.ORDINAL_POSITION
)
SELECT @DynamicJOINCondition = STUFF((SELECT distinct ' AND ' +  
                     ' t1.' + T1 + ' = ' + 't2.' + T2
               FROM cte
               FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 4,1,'');

-- Remove the first AND
SELECT @DynamicJOINCondition = RIGHT(@DynamicJOINCondition, 
                                     LEN(@DynamicJOINCondition) - 4);

SET @query = 'SELECT COUNT(*) ' +
             ' FROM  #temp321 t1 INNER JOIN Othertable t2 ON ' +
               @DynamicJOINCondition;

EXECUTE(@query);

How this works?

First I generated the JOIN condition dynamically, by getting the list of the columns names from the temp table and the other list of columns' names from the other table. Note that it. I used the columns' ORDINAL_POSITIONs, which is a metadata stored in the table information_schema.columns for each column in the database, to compare the list of columns names from the two tables. For exapmle the column with the ordincary postition 1 will be joined with the column name with the ordinary position 1 from the second table, and so so. So, you have to watch out the temp table columns positions so that the columns listed in the same order of the other columns list of the second table.


Update2:

Generate the WHERE clause dynamically:

If you want to generate the WHERE clause dynamically instead of using JOIN, in this case it will need more work. Like so:

DECLARE @DynamicWHERECondition AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);

;WITH cte
AS
(
    SELECT t1.COLUMN_NAME 'T1', t2.COLUMN_NAME 'T2'
    FROM 
    (
       SELECT
         ordinal_position, 
         column_name
       FROM information_schema.columns 
       WHERE table_name LIKE '#temp321%'
    ) t1
    INNER JOIN
    (
      SELECT 
        ordinal_position, 
        column_name
      FROM information_schema.columns 
      WHERE table_name = 'othertable'
    ) t2 ON t1.ORDINAL_POSITION = t2.ORDINAL_POSITION
), cte2 
AS
(
    SELECT t2, fieldvalue
    FROM cte t1
    INNER JOIN
    (
        SELECT FieldName, fieldvalue
        FROM
        (
            SELECT field1, field2, field3, field4
            FROM #temp321
        ) p
        UNPIVOT
        (
            fieldvalue FOR FieldName IN (field1, field2, field3, field4)
        ) AS u
    ) t2 ON t1.T2 = t2.FieldName
) 
SELECT @DynamicWHERECondition = STUFF((SELECT distinct ' AND ' +  
                      T2 + ' = ' + '''' + fieldvalue + '''' 
               FROM cte2
               FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 4,1,'');

SELECT @DynamicWHERECondition = RIGHT(@DynamicWHERECondition, LEN(@DynamicWHERECondition) - 4);
SET @query = 'SELECT COUNT(*) ' +
             ' FROM Othertable t2 WHERE ' + @DynamicWHERECondition;

EXECUTE(@query);

How this works?

Since the temp table contains only one rows with the values that will be used to form the dynamically created WHERE clause, I UNPIVOTed this one rows into two columns: fieldname: field1, field2, ... and fieldvalue: value1, value2, ....

Later I joined this unpivoted columns with the two tables I used with my first query:

    SELECT
      ordinal_position, 
      column_name
    FROM information_schema.columns 
    WHERE table_name LIKE '#temp321%';

and:

    SELECT 
      ordinal_position, 
      column_name
    FROM information_schema.columns 
    WHERE table_name = 'othertable';

With the join condition be the same as the condition in the first case, by the ordinal positions of the columns in the two tables.


Generate the WHERE clause dynamically, with dynamically UNPIVOTing the temp tables' values:

But the previous approach has a big problem. The selection of You need to unpivot the table temp dynamically like so:

SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(column_name)
                  FROM information_schema.columns 
                  WHERE table_name LIKE '#temp321%'
                  FOR XML PATH(''), TYPE
                  ).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

SET @dynamicunpivotquery = ' SELECT FieldName, fieldvalue ' +
                           ' FROM ' +
                           ' ( SELECT * FROM #temp321 ' +
                           ' ) p ' +
                           ' UNPIVOT ' +
                           ' ( ' + 
                           '   fieldvalue FOR FieldName IN (' + @cols + ' ) ' +
                           ' ) AS u ';

But, in order to use the dynamically unpivoted table later in our query, you have to create a temp table:

DECLARE @unpivotedTable TABLE(FieldName varchar(50), fieldvalue VARCHAR(50));
INSERT INTO  @unpivotedTable
exec(@dynamicunpivotquery);

So that you could use it like so:

SELECT t2, fieldvalue
FROM cte t1
INNER JOIN  @unpivotedTable t2 ON t1.T2 = t2.FieldName

Here is the updated sql with dynamic unpivot:

DECLARE @DynamicWHERECondition AS NVARCHAR(MAX);
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @dynamicunpivotquery AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
DECLARE @unpivotedTable TABLE(FieldName varchar(50), fieldvalue VARCHAR(50));

SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(column_name)
                  FROM information_schema.columns 
                  WHERE table_name LIKE '#temp321%'
                  FOR XML PATH(''), TYPE
                  ).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

SET @dynamicunpivotquery = ' SELECT FieldName, fieldvalue ' +
                           ' FROM ' +
                           ' ( SELECT * FROM #temp321 ' +
                           ' ) p ' +
                           ' UNPIVOT ' +
                           ' ( ' + 
                           '   fieldvalue FOR FieldName IN (' + @cols + ' ) ' +
                           ' ) AS u ';

INSERT INTO  @unpivotedTable
exec(@dynamicunpivotquery);

;WITH cte
AS
(
    SELECT t1.COLUMN_NAME 'T1', t2.COLUMN_NAME 'T2'
    FROM 
    (
       SELECT 
         ordinal_position, 
         column_name
       FROM information_schema.columns 
       WHERE table_name LIKE '#temp321%'
    ) t1
    INNER JOIN
    (
      SELECT 
        ordinal_position, 
        column_name 
      FROM information_schema.columns 
      WHERE table_name = 'othertable'
    ) t2 ON t1.ORDINAL_POSITION = t2.ORDINAL_POSITION
), cte2 
AS
(
    SELECT t2, fieldvalue
    FROM cte t1
    INNER JOIN  @unpivotedTable t2 ON t1.T2 = t2.FieldName
) 
SELECT @DynamicWHERECondition = STUFF((SELECT distinct ' AND ' +  
                      T2 + ' = ' + '''' + fieldvalue + '''' 
               FROM cte2
               FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 4,1,'');

SELECT @DynamicWHERECondition = RIGHT(@DynamicWHERECondition, 
                                      LEN(@DynamicWHERECondition) - 4);
SET @query = 'SELECT COUNT(*) ' +
             ' FROM Othertable t2 WHERE ' + @DynamicWHERECondition;

EXECUTE(@query);
Sign up to request clarification or add additional context in comments.

8 Comments

How can user use say Field24 = 'Value2'?. I think he is looking for a dynamic query...
sure.Thanks for your effort.
@Gamal. i am waiting...need your kind assistance.
@Gamal.Many thanks for your effort. But can you please help me to write just the where clause.Because i need to use the where clause for many other propose.I shall be very grateful to you, if you please help me to write only the where clause.Hope you get me.
@riad - OK, I will update my answer, but is the columns positions in the two tables are the same? i,e. I will genereate the where clause the same way I used to generate the JOIN condition, so that the column 1 from the temp table will compared to the value of the column1 of the other table and so on. Is this correct?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.