how to Apply AND operation in SQL - sql-server

My Query is like
Select * From T Where ID=1 AND ID=2 AND ID=3 And So On
These ID From Another Result Set Like Select ID From T2
If I Apply IN Operation SELECT * From T Where ID IN(1,2,3) It shows if there is any entry for 1 or 2 or 3 But in my requirement their should be ID 1 AND 2 AND 3
means ID IS 1,2,3 if 2 is not there result should be empty
how to apply this query.
1,2,3 is from another result set so I can't use directly and means I can't use where ID=1 AND ID=2 AND So On

Try this
SELECT * From T Where ID IN(Select ID From T2 where ID is not NULL)

The condition is applied to each row. Each row has only one ID. And so that ID can't be equal to 1 and equal to 2 and equal to 3. You need to use OR.
where ID=1 OR ID=2 OR ID=3

Your condition Where ID=1 AND ID=2 AND ID=3 is never going to fetch you any record, as ID column of each row can hold only 1 value, which can be either 1 or 2 or 3 but not all.
Ideally your query should be like
Select * From T Where ID=1 OR ID=2 OR ID=3
Above query is equivalent to
SELECT * From T Where ID IN(1,2,3)
If you want to fetch the records where id exists in another table, there are multiple ways like
1- EXISTS
Select * From T t1
Where exists
(
select 1 from t2 as t2 where t2.id=t1.id
)
2- Using IN
Select * From T t1
where id in
(
select id from t2
)

DECLARE #c2 INT
SELECT DISTINCT #c2 = COUNT(id) FROM T2
DECLARE #c1 INT
SELECT DISTINCT #c1 = COUNT(T.id) FROM T JOIN T2 on T.id=T2.id
SELECT * FROM T WHERE #c1 = #c2

Related

SQL Server query to select only values not in a list

As an example I have a table in SQL Server :
Id
1
3
5
and I have a list of values 1,2,3
What is the query to select values of my list not in the table.
Expected result :
Id
2
Here are two approaches
Using Not Exists
Select *
from string_split('1,2,3',',') A
Where not exists ( select 1 from YourTable where ID=Value )
Using a LEFT JOIN
Select A.Value
from string_split('1,2,3',',') A
left Join YourTable B on A.value=B.ID
Where B.ID is null
Both Results are
Value
2
SELECT * FROM id_table WHERE id NOT IN (1,2,3);

SQL Remove row where value exist and subsequent column that has the value

I am trying to write a SQL statement that first gets only the distinct values of column 1, I then want to compare this with the same table but remove any rows that have a value in column 2
For example, the value 10142 in FieldID when I write a select that doesn't include 10142 it only removes the 1 row but also the subsequent ID column to have no rows.
So in the screenshot, I should only see all results for only ID 634 as 633 has the FieldID value 10142.
I tried initially getting a distinct ID value into a temporary table and then filtering in another select where the FieldID was not equal to 10142 but still not seeing the correct result.
This is my query:
SELECT DISTINCT id
INTO #TEMP
FROM tbl_WorkItemCustomLatest
ORDER BY ID ASC
SELECT a.*
FROM #TEMP
INNER JOIN dbo.tbl_WorkItemCustomLatest AS A ON #TEMP.id = A.id
WHERE A.FieldID != 10142
ORDER BY A.ID ASC
Any help is much appreciated.
With NOT EXISTS:
select t.* from tbl_WorkItemCustomLatest t
where not exists (
select 1 from tbl_WorkItemCustomLatest
where id = t.id and FieldId = 10142
)
or with NOT IN:
select * from tbl_WorkItemCustomLatest
where id not in (select id from tbl_WorkItemCustomLatest where FieldId = 10142)

Discard specific results on stored procedure SQL Server

Let's say that i have a stored procedure which returns all data from two tables: A and B.
Table_A
Id Name
-----------------
1 Chuck
2 Richard
3 Arthur
Table_B
Status Nickname IdTableA
-----------------------------
1 cthulhu 1
2 Poe 3
And the query:
SELECT
a.Name, b.Status, b.Nickname
FROM
Table_A a
LEFT JOIN
Table_B b ON b.IdTableA = a.Id
If I run the stored procedure right now, it returns all the records, even when they don't have a record in table_B (as you can see, record number 2 from table_A does not exist yet -maybe tomorrow, or in a month...-). What I need to do is discard the status number 2 (which lives on table B). The problem happens when I use something like:
where b.Status = 1
or
where b.Status <> 2
Why? Because it returns only the values with Status 1. I need only discard records with status 2, but return also the records from table_A without records on table_B.
There's a way to do that?
Hope you can help me. Thanks in advance.
Does the following screenshot fulfil your requirement?
try the following:
declare #table_a table (id int, name varchar(100))
insert into #table_a select 1, 'Chuck'
union select 2, 'Richard'
union select 3, 'Arthur'
declare #table_b table (status int, nickname varchar(100), id_table_a int)
insert into #table_b
select 1, 'cthulhu', 1
union select 2, 'Poe', 3
select * from #table_a
select * from #table_b
select *
from #table_a a
left join #table_b b on a.id = b.id_table_a
where isnull(status,'') <> 2

sql select inside count - without join

There is a table called: IDs and another table called Entries.
Not all ids from Ids have entries. I do want to count how many entries have ALL the ids. if an Id has no entry I want to print 0.
Ids have PK: ID and Entries have a column ID.
If I joined them I get only the IDS having entries, but I want to get all of the IDS.
You are using INNER JOIN you can achieve this by using LEFT JOIN instead
EXAMPLE
/* Declare Temperory table for data storage */
DECLARE #MasterTable AS TABLE
(
ID INT
)
DECLARE #EntryTable AS TABLE
(
EntryID INT IDENTITY(1,1)
,MasterId INT
)
--Insert entries to Master Table
INSERT INTO #MasterTable
SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
--Insert details into details table for only 1 and 2
INSERT INTO #EntryTable
(
MasterId
)
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 3
SELECT
ID
,COUNT(EntryTable.MasterId) AS EntryCount
FROM
#MasterTable MainTable
LEFT JOIN
#EntryTable EntryTable
ON
MainTable.ID = EntryTable.MasterId
GROUP BY
ID
Use a left join
select ids.id, count(entries.id)
from ids
left join entries on entries.id = ids.id
group by ids.id
Also see this great explanation of joins
SELECT DISTINCT id, EntriesCount.entriesCount
FROM IDs
OUTER APPLY (
SELECT COUNT(id) entriesCount
FROM Entries
WHERE Entries.ids = IDs.id
) AS EntriesCount
outer apply let's you use the id from IDs in the 'where' condition from Entries.

Combine multiple results in a subquery into a single comma-separated value

I've got two tables:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
The relationship is one row of TableA - many of TableB.
Now, I want to see a result like this:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
This won't work (multiple results in a subquery):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
This is a trivial problem if I do the processing on the client side. But this will mean I will have to run X queries on every page, where X is the number of results of TableA.
Note that I can't simply do a GROUP BY or something similar, as it will return multiple results for rows of TableA.
I'm not sure if a UDF, utilizing COALESCE or something similar might work?
Even this will serve the purpose
Sample data
declare #t table(id int, name varchar(20),somecolumn varchar(MAX))
insert into #t
select 1,'ABC','X' union all
select 1,'ABC','Y' union all
select 1,'ABC','Z' union all
select 2,'MNO','R' union all
select 2,'MNO','S'
Query:
SELECT ID,Name,
STUFF((SELECT ',' + CAST(T2.SomeColumn AS VARCHAR(MAX))
FROM #T T2 WHERE T1.id = T2.id AND T1.name = T2.name
FOR XML PATH('')),1,1,'') SOMECOLUMN
FROM #T T1
GROUP BY id,Name
Output:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
1. Create the UDF:
CREATE FUNCTION CombineValues
(
#FK_ID INT -- The foreign key from TableA which is used
-- to fetch corresponding records
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #SomeColumnList VARCHAR(8000);
SELECT #SomeColumnList =
COALESCE(#SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB C
WHERE C.FK_ID = #FK_ID;
RETURN
(
SELECT #SomeColumnList
)
END
2. Use in subquery:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3. If you are using stored procedure you can do like this:
CREATE PROCEDURE GetCombinedValues
#FK_ID int
As
BEGIN
DECLARE #SomeColumnList VARCHAR(800)
SELECT #SomeColumnList =
COALESCE(#SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB
WHERE FK_ID = #FK_ID
Select *, #SomeColumnList as SelectedIds
FROM
TableA
WHERE
FK_ID = #FK_ID
END
In MySQL there is a group_concat function that will return what you're asking for.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
I think you are on the right track with COALESCE. See here for an example of building a comma-delimited string:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
You may need to provide some more details for a more precise response.
Since your dataset seems kind of narrow, you might consider just using a row per result and performing the post-processing at the client.
So if you are really looking to make the server do the work return a result set like
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
which of course is a simple INNER JOIN on ID
Once you have the resultset back at the client, maintain a variable called CurrentName and use that as a trigger when to stop collecting SomeColumn into the useful thing you want it to do.
Assuming you only have WHERE clauses on table A create a stored procedure thus:
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
Then fill a DataSet ds with it. Then
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
Finally you can add a repeater in the page that puts the commas for every line
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
In this way you will do it client side but with only one query, passing minimal data between database and frontend
I tried the solution priyanka.sarkar mentioned and the didn't quite get it working as the OP asked. Here's the solution I ended up with:
SELECT ID,
SUBSTRING((
SELECT ',' + T2.SomeColumn
FROM #T T2
WHERE WHERE T1.id = T2.id
FOR XML PATH('')), 2, 1000000)
FROM #T T1
GROUP BY ID
Solution below:
SELECT GROUP_CONCAT(field_attr_best_weekday_value)as RAVI
FROM content_field_attr_best_weekday LEFT JOIN content_type_attraction
on content_field_attr_best_weekday.nid = content_type_attraction.nid
GROUP BY content_field_attr_best_weekday.nid
Use this, you also can change the Joins
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
This will work for selecting from different table using sub query.
I have reviewed all the answers. I think in database insertion should be like:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
The comma should be at previous end and do searching by like %,X,%

Resources