SQL Server Select Where Any Column Contains 'X'

SQL Server SELECT where any column contains 'x'

First Method(Tested)
First get list of columns in string variable separated by commas and then you can search 'foo' using that variable by use of IN

Check stored procedure below which first gets columns and then searches for string:

DECLARE @TABLE_NAME VARCHAR(128)
DECLARE @SCHEMA_NAME VARCHAR(128)

-----------------------------------------------------------------------

-- Set up the name of the table here :
SET @TABLE_NAME = 'testing'
-- Set up the name of the schema here, or just leave set to 'dbo' :
SET @SCHEMA_NAME = 'dbo'

-----------------------------------------------------------------------

DECLARE @vvc_ColumnName VARCHAR(128)
DECLARE @vvc_ColumnList VARCHAR(MAX)

IF @SCHEMA_NAME =''
BEGIN
PRINT 'Error : No schema defined!'
RETURN
END

IF NOT EXISTS (SELECT * FROM sys.tables T JOIN sys.schemas S
ON T.schema_id=S.schema_id
WHERE T.Name=@TABLE_NAME AND S.name=@SCHEMA_NAME)
BEGIN
PRINT 'Error : The table '''+@TABLE_NAME+''' in schema '''+
@SCHEMA_NAME+''' does not exist in this database!'
RETURN
END

DECLARE TableCursor CURSOR FAST_FORWARD FOR
SELECT CASE WHEN PATINDEX('% %',C.name) > 0
THEN '['+ C.name +']'
ELSE C.name
END
FROM sys.columns C
JOIN sys.tables T
ON C.object_id = T.object_id
JOIN sys.schemas S
ON S.schema_id = T.schema_id
WHERE T.name = @TABLE_NAME
AND S.name = @SCHEMA_NAME
ORDER BY column_id


SET @vvc_ColumnList=''

OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @vvc_ColumnName

WHILE @@FETCH_STATUS=0
BEGIN
SET @vvc_ColumnList = @vvc_ColumnList + @vvc_ColumnName

-- get the details of the next column
FETCH NEXT FROM TableCursor INTO @vvc_ColumnName

-- add a comma if we are not at the end of the row
IF @@FETCH_STATUS=0
SET @vvc_ColumnList = @vvc_ColumnList + ','
END

CLOSE TableCursor
DEALLOCATE TableCursor

-- Now search for `foo`


SELECT *
FROM testing
WHERE 'foo' in (@vvc_ColumnList );

2nd Method
In sql server you can get object id of table then using that object id you can fetch columns. In that case it will be as below:

Step 1: First get Object Id of table

select * from sys.tables order by name    

Step 2: Now get columns of your table and search in it:

 select * from testing where 'foo' in (select name from sys.columns  where  object_id =1977058079)

Note: object_id is what you get fetch in first step for you relevant table

SQL SELECT WHERE field contains words

Rather slow, but working method to include any of words:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
OR column1 LIKE '%word2%'
OR column1 LIKE '%word3%'

If you need all words to be present, use this:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
AND column1 LIKE '%word2%'
AND column1 LIKE '%word3%'

If you want something faster, you need to look into full text search, and this is very specific for each database type.

Bigquery Select from table where any column contains 'FINISHED'

Below is for BigQuery Standard SQL
Should be good start for you :)



#standardSQL
SELECT <columns to output>
FROM yourTable AS t
WHERE REGEXP_CONTAINS(LOWER(TO_JSON_STRING(t)), 'finished')

You can test/play with it with below dummy data

#standardSQL
WITH yourTable AS (
SELECT 'a' AS x, 'b' AS y, 'c' AS z UNION ALL
SELECT 'finished', '', '' UNION ALL
SELECT '', 'Bigquery Select from table where any column contains "FINISHED"','' UNION ALL
SELECT '', '', 'aaa' UNION ALL
SELECT 'finished', 'bbb', 'finished'
)
SELECT *
FROM yourTable AS t
WHERE REGEXP_CONTAINS(LOWER(TO_JSON_STRING(t)), 'finished')

Update

Note: if you have your search word as a part of at least one column name - above will return all rows! To address this - you would need to invest a little bit more coding

For example, for simple schema (with no record or repeated) this would be a

#standardSQL
SELECT <columns to output>
FROM yourTable AS t
WHERE (SELECT COUNTIF(SPLIT(zzz, ':')[SAFE_OFFSET(1)] LIKE '%finished%')
FROM UNNEST(SPLIT(SUBSTR(LOWER(TO_JSON_STRING(t)),2,LENGTH(TO_JSON_STRING(t))-2))) AS zzz
) > 0

You can test this with below

#standardSQL
WITH yourTable AS (
SELECT 'a' AS x, 'b' AS y, 'c' AS col_finished UNION ALL
SELECT 'finished', '', '' UNION ALL
SELECT '', 'Bigquery Select from table where any column contains "FINISHED"','' UNION ALL
SELECT '', '', 'aaa' UNION ALL
SELECT 'finished', 'bbb', 'finished'
)
SELECT *
FROM yourTable AS t
WHERE (SELECT COUNTIF(SPLIT(zzz, ':')[SAFE_OFFSET(1)] LIKE '%finished%')
FROM UNNEST(SPLIT(SUBSTR(LOWER(TO_JSON_STRING(t)),2,LENGTH(TO_JSON_STRING(t))-2))) AS zzz
) > 0

SQL Return rows where column 1 contains X and Y

Here's one way to do it. Use an EXISTS predicate that uses a correlated subquery to check for the existence of the "other" row. This assumes that you only want to return rows that have values of 'Email' and 'Appointment' in the Activity column, and to exclude rows that have any other value for activity. (This isn't the most efficient way to do it.)

SELECT t.account
, t.activity
FROM example_table t
WHERE t.activity IN ('Email','Appointment')
AND EXISTS ( SELECT 1
FROM example_table d
WHERE d.account = t.account
AND d.activity =
CASE t.activity
WHEN 'Email' THEN 'Appointment'
WHEN 'Appointment' THEN 'Email'
END
)

ADDITION

Here's the approach above applied to the original query (which is later supplied as a comment on another answer...)

SELECT t.ACCOUNT
, t.COMPANY
, h.RESPONSE
, h.DAT_ AS Resp_Date
, h.USERNAME
, DATE_FORMAT(p.ENDDATE,'%M') AS Renewal
, t.OWNER
, h.CustomerStatus
, h.Contact
, a.ANAL14 AS APPDATE
FROM TELRCMxxx t
JOIN TELCOMxxx h
ON t.ACCOUNT = h.ACCOUNT
AND h.ACTIVITY in ('Appointment','email')
AND EXISTS
( SELECT 1
FROM TELCOMxxx b
WHERE b.ACCOUNT = h.ACCOUNT
AND b.ACTIVITY = CASE h.ACTIVITY
WHEN 'email' THEN 'Appointment'
WHEN 'Appointment' THEN 'email'
END
)
LEFT
JOIN ACCSTOxxx p
ON t.ACCOUNT = p.ACCOUNT
LEFT
JOIN RCMANLxxx a
ON t.ACCOUNT = a.ACCOUNT

NOTES: original query has a LEFT join to h, but the "outerness" of the join operation is negated by the WHERE clause, which effectively verifies h.ACTIVITY IS NOT NULL. The LEFT keyword is removed, and the h.ACTIVITY IN ('Appointment','email') predicate is moved from the WHERE clause to the ON clause of the join. But that doesn't really change anything about the query.

The change to the query is the addition of an "EXISTS" predicate that checks for the existence of another row in h, matching on ACCOUNT, and matching either 'Appointment' or 'email', as the opposite of the value in the row from h being checked.

Note that this:

            AND b.ACTIVITY = CASE h.ACTIVITY 
WHEN 'email' THEN 'Appointment'
WHEN 'Appointment' THEN 'email'
END

is equivalent to:

            AND ( ( b.ACIVITY = 'email' AND h.ACTIVITY = 'Appointment' )
OR
( b.ACIVITY = 'Appointment' AND h.ACTIVITY = 'email' )
)

END ADDITION


If you need to return all rows for the account, including other values for activity, then you remove the t.Activity IN predicate from the WHERE clause on the outer query, and just check for the existence of both an 'Email' and 'Appointment' row for that account:

SELECT t.account
, t.activity
FROM example_table t
WHERE EXISTS ( SELECT 1
FROM example_table e
WHERE e.account = t.account
AND e.activity = 'Email'
)
AND EXISTS ( SELECT 1
FROM example_table a
WHERE a.account = t.account
AND a.activity = 'Appointment'
)

This is not the most efficient approach, but it will return the specified result.

For large sets, a (usually) more efficient approach is to use a JOIN operation.

To get a list of distinct account values that have both 'Email' and 'Appointment' rows:

SELECT e.account
FROM example_table e
JOIN example_table a
ON a.account = e.account
AND a.activity = 'Appointment'
WHERE e.activity = 'Email'
GROUP BY e.account

To get all rows from the table for those accounts:

SELECT t.account
, t.activity
FROM example_table t
JOIN ( SELECT e.account
FROM example_table e
JOIN example_table a
ON a.account = e.account
AND a.activity = 'Appointment'
WHERE e.activity = 'Email'
GROUP BY e.account
) s
ON s.account = t.account

If you only want to return rows with particular values for activity, you can add a WHERE clause, e.g.

 WHERE t.activity IN ('Email','Appointment','Foo')

How can I search all columns in a table?


SELECT ...
FROM yourtable
WHERE 'val' IN (field1, field2, field3, field4, ...)

if you're looking for exact full-field matches. If you're looking for substring matches, you'll have to go about it the long way:

WHERE field1 LIKE '%val%' or field2 LIKE '%val%' etc....

Identify all columns containing only a single value (e.g. 0,0.00, Z, Y, N)

Here's one way you could go about this. For each column of the specified table, it does a count of rows that match your criteria and, if the column's row count matches that of the table's, the column is added to the XML list for review.

NOTE:

Given your number of columns and possible row counts, this process could take a while.

DECLARE @Columns table ( column_name varchar(255), pk INT IDENTITY(1,1) );
DECLARE
@TableName varchar(50) = 'tblClients',
@Criteria varchar(255) = 'IN (''0'', ''0.00'', ''Z'', ''N'', ''Y'')',
@sql nvarchar(MAX),
@rows int;

/* Get the current row count for @TableName */

SET @sql = 'SELECT @count = COUNT( DISTINCT [' + @col + '] ) FROM ' + @TableName + ';';
EXEC sp_executesql @sql, N'@count int OUT', @count = @rows OUT;

/* Create an XML object to store fields that match criteria */
DECLARE @List xml = '<root><columns></columns></root>';

-- Insert the table name and number of rows processed.
SET @List.modify(
'insert
<table>
<name>{sql:variable("@TableName")}</name>
<rows>{sql:variable("@rows")}</rows>
<criteria>{sql:variable("@Criteria")}</criteria>
</table>
as first
into (//root)[1]'
);

/* Collect a list of column names for the specified table */

INSERT INTO @Columns ( column_name )
SELECT [name] FROM sys.columns WHERE object_id = OBJECT_ID( @TableName ) ORDER BY column_id;

/* For-each column, check if it contains: [ 0 | 0.00 | Z | N | Y ] */

DECLARE @pk int = 1, @col varchar(255), @count int;
WHILE @pk <= ( SELECT MAX ( pk ) FROM @Columns )
BEGIN

-- Current column.
SELECT @col = column_name FROM @Columns WHERE pk = @pk;

-- Get count of rows for this column with the specified values.
SET @sql = 'SELECT @count = COUNT( DISTINCT [' + @col + '] ) FROM ' + @TableName + ' WITH (NOLOCK) WHERE CAST( [' + @col + '] AS varchar(MAX) ) ' + @Criteria + ';';
EXEC sp_executesql @sql, N'@count int OUT', @count = @count OUT;

-- Insert the column for review if its count matches the table row count.
IF @count BETWEEN 1 AND 2
SET @List.modify(
'insert
<column>
<name>{sql:variable("@col")}</name>
<count>{sql:variable("@count")}</count>
</column>
into (//root/columns)[1]'
);

-- Next column.
SET @pk = @pk + 1;

END

/* SELECT @List results */
SELECT @List AS List;

In my case, the following XML is returned. These columns match your criteria of ones that should be reviewed.

<root>
<table>
<name>tblClients</name>
<rows>143</rows>
<criteria>IN ('0', '0.00', 'Z', 'N', 'Y')</criteria>
</table>
<columns>
<column>
<name>WebPortal</name>
<count>143</count>
</column>
<column>
<name>EnforceQTY</name>
<count>143</count>
</column>
<column>
<name>CheckForPrepaid</name>
<count>143</count>
</column>
<column>
<name>ReportNet</name>
<count>143</count>
</column>
<column>
<name>ActiveClient</name>
<count>143</count>
</column>
</columns>
</root>

No null values in any column in SQL Server

This should do it

SET NOCOUNT ON;

-- populate table
create table my_test_table
(
foo1 int,
foo2 int,
foo3 int,
foo4 int,
foo5 int
)

INSERT INTO my_test_table
select 1,2,3,4,5

INSERT INTO my_test_table
select 1,2,null,4,5

INSERT INTO my_test_table
select 1,2,3,4,null

INSERT INTO my_test_table
select 1,null,3,4,null

-- Actual query needed for question
declare @columns table
(
ident int identity(1,1),
column_name varchar(255)
)

INSERT INTO @columns (column_name)
SELECT c.[name]
FROM sys.columns c
INNER JOIN sys.objects o ON (c.object_id = o.object_id)
WHERE o.[name] = 'my_test_table'
ORDER BY c.column_id

declare @table_count int = (select COALESCE(count(ident),0) from @columns)
declare @counter int = 1

declare @column_name varchar(255)
declare @sql nvarchar(max) = ''

while (@table_count > 0 AND @counter <= @table_count)
BEGIN
select @column_name = column_name
from @columns
where ident = @counter

set @sql += ', count(' + @column_name + ') as [' + @column_name + '_total]'

set @counter += 1
END

exec('select count(*) as total' + @sql + ' from my_test_table')

make sure you change the name of "my_test_table" to whatever the table name is.

Result

total   | foo1_total  |foo2_total    |foo3_total   |foo4_total   |foo5_total
--------+-------------+--------------+-------------+-------------+-----------
4 | 4 | 3 | 3 | 4 | 2

where the column total doesn't match the total (first column) then it has some NULL's.

TEST: http://rextester.com/AVB29103



Related Topics



Leave a reply



Submit