Searching Multiple Columns with Multiple Values SQL - sql-server

I know it is posible to serach multiple columns with one value.
I would like to serach 3-4 columns for 4 maybe 5 values
I want to check if any of my choosen columns have a certain value in them.
Example
Column 1 | Column 2 | Column 3 | Column 4
| | |
Hello | | | = True
| | |
| Goodbye | | = True
| | Hello | Goodbye = True
| | |
| Hello | | = True
| | |
| | Goodbye | = True
In the example I would like SQL to pull the data from all of the lines that have Hello or Goodbye even both in some cases.
Is there a way to do what I want?

There is one more way...
SELECT *
FROM TableName
WHERE 'Value1' IN (Col1,Col2,Col3...) OR 'Val2' in (Col1,Col2,Col3...) OR ...

If it's only 3 or 4 columns, the simplest solution would be something like this:
SELECT *
FROM TableName
WHERE Column1 IN('Hello', 'Goodbye')
OR Column2 IN('Hello', 'Goodbye')
OR Column3 IN('Hello', 'Goodbye')
OR Column4 IN('Hello', 'Goodbye')

Forgot to follow with my solution: I needed to join 2 tables and search across the columns. They ****ed up and made the id of t1 a varchar, smh, and some of them had nulls so we needed to check for them lest our results were ****ed (this is why the selected answer wouldn't work for me). You don't need the aliases but if you were going deeper it helps keep things straight.
Use "+" operator to add columns to a WHERE, check for nulls, and caste if you need too.
SELECT *
FROM Table1 AS t1
LEFT OUTER JOIN Table2 AS t2
ON t1.id = t2.id
WHERE( ISNULL(CONVERT(VARCHAR,t1.id),'') + ISNULL(t1.name,'') + ISNULL(t1.desc,'') + ISNULL(t2.company,'')) LIKE '%xbox%'

Related

Use IN operator along with NOT LIKE considering wild card matching

I am having two tables.
TableA(% is a wild card character)
---------------
str |
---------------
abc% |
xyz% |
pop% |
---------------
TableB
--------------------
id | name | domain |
--------------------
1 | Paul | zzz.ko |
2 | John | abc.lo |
3 | Kal | pop.cm |
--------------------
I want to fetch all the records from TableB where domain does not match with TableA str field(
wild card matching).
A crude query would look like this:
select * from TableB b
where not exists (select 1 from TableA a where b.domain like a.str)
Also, you might want to avoid using "str" as a column name.

Cross join, display table 2 column value base on table1

I have two tables in SQL Server, Say in table1 I have two columns Key1Display and Key2Display, they are of datatype bit and used to control whether to display the values in table2, and table 2 will have 2 columns Key1 and Key2.
What I am trying to achieve is a sort of cross join, say if table 1 has 3 rows:
| Key1Display | Key2Display |
+---------------------+------------------+
| 0 | 1 |
| 1 | 0 |
| 1 | 1 |
Say in table 2 there are 2 rows
| Key1 | Key2 |
+---------------------+------------------+
| Row1Key1value | Row1Key2value |
| Row2Key1value | Row2Key2value |
Then based on these two tables, I want to have a query to display 6 (2*3) rows and 1 column of results like this:
null:Row1Key2value
Row1Key1Value:null
Row1Key1Value:Row1Key2value
null:Row2Key2value
Row1Key2Value:null
Row1Key2Value:Row2Key2value
So something like:
select
case when t1.Key1Display = 1 then coalesce(t2.Key1,'??') else 'null' end
+ ':' + case when t1.Key2Display = 1 then coalesce(t2.Key2,'??') else 'null' end
-- And so on for as many keys as you have
from table1 t1
cross join table2 t2

How to have a child group span across three columns?

What I'm trying to do
In my report, I am trying to get some basic data in a tablix. In this tablix there is one main summary row and detail rows inside it. What I want to do is put the details in the child row but split into three columns.
For example my tablix looks like this right now
Row11| Row12| Row13 |
1 | 5 | 4 |
| Column1 | Column2|
| 1 | 4 |
| 2 | 5 |
| 3 | 6 |
2 | 20 | 25 |
Column1 Column2 |
| 7 | 8 |
| 9 | 5 |
| 3 | 6 |
(This is just a demo table. The number of columns in my application is not necessarily this number and it should be irrelevant anyway)
How I want it to look like:
Row11| Row12| Row13 |
1 | 5 | 4 |
| Column1 | Column2| Column1 | Column2| Column1 | Column2|
| 1 | 4 | 2 | 5 | 3 | 6 |
2 | 20 | 25 |
| Column1 | Column2| Column1 | Column2| Column1 | Column2|
| 7 | 8 | 9 | 5 | 3 | 6 |
I just want to split the detail table into three columns. I have tried various approaches but in vein.
What approaches have I tried?
Attaching a sub report method. I attached a sub report and divided the report into three separate tables and split the columns in this order. This works except that it is terribly slow when trying to get large amount of data. Really do not want to do this.
The method mentioned here. Did not work.
I have been experimenting with the SQL itself as well but SQL does not look like to be an issue here.
Tried with Matrix instead of tablix too trying to push my limits but did not succeed.
Side note: If it matters I am using SSRS SDK for PHP and grabbing the PDFs from the Report Server and using Visual Studio to design the reports.
This seems such a simple thing but I am stuck with this. Has anybody in a situation like this before?
Please let me know if you need more clarifications.
Create three detail tables, adjust which rows get shown in each, and put them in a List.
This solution works on the assumption that your raw data looks something like this:
Add a table report item and add the Column1 and Column2 data to it, leaving the grouping as just the details. Right-click the detail row, and go to Row Visibility.
Switch this to 'Show or hide based on an expression', and add this expression:
=IIF(RowNumber("tblFirstColumn") MOD 3 = 1, False, True)
This will make only the first, fourth, seventh etc. record show in that table. Paste two copies of this table next to the first, and adjust the row visibility expression on each:
=IIF(RowNumber("tblSecondColumn") MOD 3 = 2, False, True)
=IIF(RowNumber("tblThirdColumn") MOD 3 = 0, False, True)
Next add a List item. Change the row grouping of the list to group by Row11, add each row field to the top of this list (as text boxes or a non-grouped table), and move the three detail tables into the bottom of the list.
This should perform better than using subreports. I understand that when using subreports the datasets will be queried with every instance of that subreport. With all the design in one report, the queries should only run once.
Method 1: main tablix = three columns with TWO detail rows. In the 2nd detail row merge the three columns together. Create a new tablix for the detail information and put it inside the merged detail cell.
Method 2: main tablix = six columns and two detail rows. In the 1st detail row merge cells 1/2, 3/4, and 5/6 together.
I had to tackle a same problem once and the way I did it is by "Inserting a TABLIX inside a TABLIX". I believe if you follow the link below that shuold resolve what you are looking for:
http://www.sqlcircuit.com/2012/03/ssrs-how-to-show-tablix-inside-tablix.html
Waht I have additionaly done in my report to increase the width of the nested tablix so that it does not affect the width on the main tablix is:
1) On the the row above the insertted tablix I have created a column and kept it empty and merged the cell below it where the nested tablix should be.
2) now you can increase the size of the empty column (make the borders invisible) to what ever the width of the inserted TABLIX you would like.
Hope this helped.
For what it's worth (I see you have already accepted an answer), I think this could be done primarily within SQL if you wished.
Assuming your raw data looks like this:
/-------------------------------------------\
| Row11 | Row12 | Row13 | Column1 | Column2 |
|-------+-------+-------+---------+---------|
| 1 | 5 | 4 | 1 | 4 |
| 1 | 5 | 4 | 2 | 5 |
| 1 | 5 | 4 | 3 | 6 |
| 2 | 20 | 25 | 3 | 6 |
| 2 | 20 | 25 | 7 | 8 |
| 2 | 20 | 25 | 9 | 5 |
\-------------------------------------------/
Let's create demo data to illustrate:
CREATE TABLE data (
Row11 INT,
Row12 INT,
Row13 INT,
Column1 INT,
Column2 INT
)
INSERT INTO data
SELECT 1,5,4,1,4
UNION
SELECT 1,5,4,2,5
UNION
SELECT 1,5,4,3,6
UNION
SELECT 2,20,25,7,8
UNION
SELECT 2,20,25,9,5
UNION
SELECT 2,20,25,3,6
You could aggregate each summary and detail row like this:
SELECT DISTINCT d.Row11,
d.Row12,
d.Row13,
dfirst.Column1,
dfirst.Column2,
dsecond.Column1,
dsecond.Column2,
dthird.Column1,
dthird.Column2
FROM data d
CROSS APPLY
(
SELECT TOP 1 Column1, Column2
FROM data d1
WHERE d1.Row11 = d.Row11 AND d1.Row12 = d.Row12 AND d1.Row13 = d.Row13
ORDER BY 1,2
) dfirst
CROSS APPLY
(
SELECT Column1, Column2
FROM
(
SELECT Column1, Column2, ROW_NUMBER() OVER (ORDER BY Column1, Column2) AS rownumber
FROM data d1
WHERE d1.Row11 = d.Row11 AND d1.Row12 = d.Row12 AND d1.Row13 = d.Row13
) drows
WHERE rownumber = 2
) dsecond
CROSS APPLY
(
SELECT TOP 1 Column1, Column2
FROM data d1
WHERE d1.Row11 = d.Row11 AND d1.Row12 = d.Row12 AND d1.Row13 = d.Row13
ORDER BY 1 DESC,2 DESC
) dthird
Which gives the results:
/-----------------------------------------------------------------------------------\
| Row11 | Row12 | Row13 | Column1 | Column2 | Column1 | Column2 | Column1 | Column2 |
|-------+-------+-------+---------+---------+---------+---------+---------+---------|
| 1 | 5 | 4 | 1 | 4 | 2 | 5 | 3 | 6 |
| 2 | 20 | 25 | 3 | 6 | 7 | 8 | 9 | 5 |
\-----------------------------------------------------------------------------------/
It should then be relatively trivial to group this in the table in your SSRS report by Row11, Row12, Row13, placing the values for Row11, Row12 and Row13 into the Group Header row and the values for all 6 Column1 and Column2 values into the detail row:
Design:
Results:
Note: this only works for 3 (or fewer) pairs of Column1/Column2 values per tuple of Row11, Row12, Row13 values.

Unpivot SQL each row in SQL table to key-value pairs with group IDs

Running SQL Server 2012, I have a table in the following format:
ENC_ID | Name | ED_YN | Seq
-------------------------------------
1234 | John | Y | 1
1234 | Sally | N | 2
2345 | Chris | N | 1
2345 | Sally | N | 2
I would like to unpivot this into a entity-attribute-value list (if that's the right terminology - I am thinking of them as key-value pairs grouped by IDs), with the following format:
ENC_ID | Seq | Key | Value
--------------------------------------
1234 | 1 | Name | John
1234 | 1 | ED_YN | Y
1234 | 2 | Name | Sally
1234 | 2 | ED_YN | N
2345 | 1 | Name | Chris
2345 | 1 | ED_YN | N
2345 | 2 | Name | Sally
2345 | 2 | ED_YN | N
I have seen various answers to this using UNION or UNPIVOT, but these solutions tend to be long and must be closely customized to the table. I'm looking for a solution that can be reused without a great deal of rewriting as this pattern solves a problem I expect to run into frequently (ingesting data from star-schema into Tableau via extracts, where I don't necessarily know the number of value columns).
The closest thing I've found to solve this is this question/answer but I haven't had success altering the solution to add ENC_ID and Seq to each row in the result table.
Thanks.
I will use Cross Apply with table valued Constructor to do this unpivoting
select ENC_ID, Seq, Key, Value
from yourtable
cross apply
(values ('Name',Name),
('ED_YN',ED_YN)) CS (Key,Value)
You can try below query. This uses classic UNPIVOT syntax.
Since I am unsure about your column types I have casted both of them as varchar(100). You can increase length from 100.
Working sql fiddle demo link :
select enc_id,seq, k [key],v [value] from
(select enc_id,seq,cast(name as varchar(100)) as name, cast(ed_yn as varchar(100)) as ed_yn from r)s
UNPIVOT
( v for k in ([name],[ed_yn])
)up

SQLite Complex Query Help

I have a very complex query going on in SQLite, and I need a bit of help understanding how to do it.
The following example is of my Database:
Category:
CatID | CatTitle
----------------
1 | XYZ
2 | Sample
Content:
ItemID | ItemCatID | ItemText | ItemText2 | ItemText3 | ItemText4
-----------------------------------------------------------------
1 | 1 | Test | Bla | Sample | MoreContent
2 | 1 | Test2 | BlaBla | Sample2 | Other Content
3 | 2 | Test3 | BlaBla2 | Sample3 | Other Content2
Now, I basically want to do a query, on a search string.. (i.e. "%XYZ%" with the wildcards) and I want to search not only the CatTitle, but also ItemText, ItemText2 and ItemText3
The parameters I want to return though are: CatID, CatTitle, ItemID, and if possible, "ItemFilteredText" (which can be anything from ItemText to ItemText4, depending on which is the match)
Heres the thing, If the Query Matches CatTitle, then if it returns ItemID, it should be the FIRST ItemID and NOT the LAST ItemID
I have the following SQL somewhat working...
select DISTINCT Category.CatID,
Category.CatTitle,
Content.ItemID,
Content.ItemText,
Content.ItemText2,
Content.ItemText3
from Content,Category
where Category.CatID = Content.ItemCatID
AND ( Category.CatTitle like'%XYZ%'
OR Content.ItemText like '%XYZ%'
OR Content.ItemText2 like '%XYZ%'
OR Content.ItemText3 like '%XYZ%')
GROUP BY Category.CatTitle ORDER BY Category.CatID ASC
It returns the data... but Grouping By Category.CatTitle means that Content.ItemID would return 2, instead of 1
Any Ideas?
Assuming that you are using integers for content.ItemID and the first result is characterized by a lower ItemID modify the query to include min(Content.ItemID)
select DISTINCT Category.CatID, Category.CatTitle, min(Content.ItemID), Content.ItemText, Content.ItemText2, Content.ItemText3 from Content,Category where Category.CatID = Content.ItemCatID AND (Category.CatTitle like'%XYZ%' OR Content.ItemText like '%XYZ%' OR Content.ItemText2 like '%XYZ%' OR Content.ItemText3 like '%XYZ%') GROUP BY Category.CatTitle ORDER BY Category.CatID ASC
should do the work.

Resources