This shouldn't be hard but somehow I am unable to make this work. So I have two tables: Splanning_Buildings and Splanning_RoomData. The primary key of OBJECTID in the Splanning_Buildings table is represented as Objectid_bldg in the Splanning_RoomData table.
What I need is to select all rows from the Splanning_Buildings table in such a way that if its value is found inside the Splanning_RoomData table then show the value as "Existing" string; but if not found in Splanning_RoomData then show as blank.
This is SQL Server 2012.
Here is my sql:
SELECT t1.objectid, name, t2.building_n FROM splanning_buildings t1 LEFT JOIN splanning_roomdata t2 ON t1.objectid = t2.objectid_bldg WHERE t2.objectid_bldg IS NULL
SELECT t1.objectid, name, t2.building_n FROM splanning_buildings t1 LEFT JOIN splanning_roomdata t2 ON t1.objectid = t2.objectid_bldg
The first query returns all rows from the splanning-buildings table except the row which exists the splanning_RoomData table; so t2.building_n is 'null'. Makes sense.
The second query returns all rows from the buildings table but multiple t2.buildings_n rows.
None of these are the desired results! I guess I need some kind of sql Case() function?
Any idea?
Thanks!
SELECT t1.objectid, name,
CASE WHEN (EXISTS(SELECT TOP(1) 1 FROM splanning_roomdata t2 WHERE t1.objectid = t2.objectid_bldg )) THEN
'Exists'
ELSE 'Not exists' END AS [status]
FROM splanning_buildings t1
select objectid,
(select top 1 1 from room_data
where objectid_bldg=objectid)
as roomdata_exists from buildings
I simplified your table names a little bit - hope you can still make sense of it. ;-)
Related
I have two tables in MSSQL.
Table1
Table2
I want to update the Status column in Table 1 to "YES" if the same Ticket ID, House and Part Number exists in Table 2. After updating, Table 1 should be like,
How can I achieve this?
Thanks
a simple EXISTS() will do the job
UPDATE t1
SET Status = 'Yes'
FROM Table1 t1
WHERE EXISTS
(
SELECT *
FROM Table2 t2
WHERE t1.TicketID = t2.TicketID
AND t1.House = t2.House
AND t1.PartNumber = t2.PartNumber
)
or an INNER JOIN will gives you the query that you want
I am querying a Microsoft SQL Server 2012.
The primary table (T1) structure contains account details:
AccountID, Name, Address
This table is dropped and recreated using external data nightly. We need to display this information but also need to exclude some of the records. Since we have no access to the external data we can't just add a column.
So we created a table (T2) to mark all the accounts we would like to exclude. It just has 2 fields:
AccountNo, Type
So we populated T2 and for every account we wanted to exclude from the display we gave the Type field a value of 'ex' (for exclude). We have no entries for the account we want to display.
When I execute the following query:
select T1.AccountID as acct, T1.Name as name, T1.Address as add
from T1
left join T2 on T1.AccountID = T2.AccountNo
WHERE T2.Type != 'ex'
The above query returns and empty set.
If I run a query to look for the value 'ex' (remove the !):
select T1.AccountID as acct, T1.Name as name, T1.Address as add
from T1
left join T2 on T1.AccountID = T2.AccountNo
WHERE T2.Type = 'ex'
The query returns the rows with that field populated with 'ex', as you expect.
I can search for NULL or NOT null with success but we need to use this extra table to do some other data manipulation in the future. In other words, we will not just be populating this field with "ex".
I'm wondering why I can't query the field in the joined table by looking for a Boolean false for a string. Is is because since the column doesn't exist in the table that is joined (T2) that it doesn't actually exist in the data set?
If that's the case how would I execute a query to return the records that do not equal a value in the joined table, whether that record exists in the joined table or not.
You can use the ISNULL solution like mentioned in the comments.
Another way you could write the query is this:
SELECT #t1.AccountID AS acct, #t1.Name AS [name], #t1.Address AS [add]
FROM #t1
LEFT JOIN #t2 ON #t1.AccountID = #t2.AccountNo
AND #t2.type = 'ex' --In case you add additional types to #t2
WHERE #t2.AccountNo IS NULL;
Suppose you have two tables in a SQL Server database with the same schema for both tables. I want to compare a single column on both tables and find the values that are missing in table1 but are in table2. I've been doing this manually in Excel with a macro after I've gotten a distinct list in each query, but it would be less work if I had a query. How can I find the missing records via T-SQL? I'd like to do this for the following data types: datetime, nvarchar & bigint.
SELECT DISTINCT [dbo].[table1].[column1]
FROM [dbo].[table1]
ORDER BY [dbo].[table1].[column1] DESC
SELECT DISTINCT [dbo].[table2].[column1]
FROM [dbo].[table2]
ORDER BY [dbo].[table2].[column1] DESC
There are several ways you can do this...
LEFT JOIN:
SELECT DISTINCT t2.column1
FROM dbo.table2 t2
LEFT JOIN dbo.table1 t1
ON t2.Column1 = t1.Column1
WHERE t1.Column1 IS NULL
NOT EXISTS:
SELECT DISTINCT t2.column1
FROM dbo.table2 t2
WHERE NOT EXISTS (
SELECT 1
FROM dbo.table1 t1
WHERE t1.column1 = t2.column1
)
NOT IN:
SELECT DISTINCT t2.column1
FROM dbo.table2 t2
WHERE t2.column1 NOT IN (
SELECT t1.column1
FROM dbo.table1 t1
)
There are some slight variations in the behavior and efficiency of these approaches... based mostly on the presence of NULL values in columns, so try each approach to find the most efficient one that gives the results you expect.
SELECT DISTINCT [dbo].[table2].[column1]
FROM [dbo].[table2]
except
SELECT DISTINCT [dbo].[table1].[column1]
FROM [dbo].[table1]
All the values of column1 in Table2 that are not present in column1 of Table1
basically, you can use LEFT JOIN.
TableB is set as the main table in this case. By joining it with TableA using LEFT JOIN, the the records that have no match on TableA a will still be in the result list but their values are NULL. So to filter out non matching records, add a filtering condition which only select records with NULL value on tableA.
SELECT b.*
FROM tableB b
LEFT JOIN tableA a
ON a.column1 = b.column1
WHERE a.column1 IS NULL
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
SQL Server 2005 onwards you could use Except
SELECT DISTINCT [dbo].[table2].[column1]
FROM [dbo].[table2]
Except
SELECT DISTINCT [dbo].[table1].[column1]
FROM [dbo].[table1]
I am running a query that returns records from the LEFT of the EXCEPT that are not on the right query;
USE AdventureWorks;
GO
SELECT ProductID
FROM Production.Product
EXCEPT
SELECT ProductID
FROM Production.WorkOrder;
Lets say there are 6 records returned (there are 6 records in Production.Product table, that are not in Production.WorkOrder)
How would I write the query to update the 6 records into Production.WorkOrder table?
insert into workorder (productid)
select productid from product where productid not in (select productid from workorder)
This will insert into workorder all the productid's in the product table that aren't already in workorder.
I'd use a left join, like this:
USE AdventureWorks;
GO
SELECT p.ProductID
FROM Production.Product p
LEFT
JOIN Production.WorkOrder wo
ON p.ProductID = wo.ProductID
WHERE wo.ProductID IS NULL;
This will return all the ProductID values from Product that do not appear in WorkOrder. The problem with the other answer (WHERE NOT IN) is that the sub-query will execute once/row, and if the tables are large, this will be really slow. A LEFT JOIN will only execute once, and then SQL will match the rows up - on a small table, there won't be much difference in practice, but on a larger table or in a production database, the difference will be immense.
Just turn your query into an INSERT?
INSERT INTO Production.WorkOrder(ProductID, ...)
SELECT ProductID, ...
FROM Production.Product
EXCEPT
SELECT ProductID
FROM Production.WorkOrder;
I have the following Query and i need the query to fetch data from SomeTable based on the filter criteria present in the Someothertable. If there is nothing present in SomeOtherTable Query should return me all the data present in SomeTable
SQL SERVER 2005
SomeOtherTable does not have any indexes or any constraint all fields are char(50)
The Following Query work fine for my requirements but it causes performance problems when i have lots of parameters.
Due to some requirement of Client, We have to keep all the Where clause data in SomeOtherTable. depending on subid data will be joined with one of the columns in SomeTable.
For example the Query can can be
SELECT
*
FROM
SomeTable
WHERE
1=1
AND
(
SomeTable.ID in (SELECT DISTINCT ID FROM SomeOtherTable WHERE Name = 'ABC' and subid = 'EF')
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC' and subid = 'EF')
)
AND
(
SomeTable.date =(SELECT date FROM SomeOtherTable WHERE Name = 'ABC' and subid = 'Date')
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC' and subid = 'Date')
)
EDIT----------------------------------------------
I think i might have to explain my problem in detail:
We have developed an ASP.net application that is used to invoke parametrize crystal reports, parameters to the crystal reports are not passed using the default crystal reports method.
In ASP.net application we have created wizards which are used to pass the parameters to the Reports, These parameters are not directly consumed by the crystal report but are consumed by the Query embedded inside the crystal report or the Stored procedure used in the Crystal report.
This is achieved using a table (SomeOtherTable) which holds parameter data as long as report is running after which the data is deleted, as such we can assume that SomeOtherTable has max 2 to 3 rows at any given point of time.
So if we look at the above query initial part of the Query can be assumed as the Report Query and the where clause is used to get the user input from the SomeOtherTable table.
So i don't think it will be useful to create indexes etc (May be i am wrong).
SomeOtherTable does not have any
indexes or any constraint all fields
are char(50)
Well, there's your problem. There's nothing you can do to a query like this which will improve its performance if you create it like this.
You need a proper primary or other candidate key designated on all of your tables. That is to say, you need at least ONE unique index on the table. You can do this by designating one or more fields as the PK, or you can add a UNIQUE constraint or index.
You need to define your fields properly. Does the field store integers? Well then, an INT field may just be a better bet than a CHAR(50).
You can't "optimize" a query that is based on an unsound schema.
Try:
SELECT
*
FROM
SomeTable
LEFT JOIN SomeOtherTable ON SomeTable.ID=SomeOtherTable.ID AND Name = 'ABC'
WHERE
1=1
AND
(
SomeOtherTable.ID IS NOT NULL
OR
0=(SELECT Count(1) FROM SomeOtherTable WHERE spName = 'ABC')
)
also put 'with (nolock)' after each table name to improve performance
The following might speed you up
SELECT *
FROM SomeTable
WHERE
SomeTable.ID in
(SELECT DISTINCT ID FROM SomeOtherTable Where Name = 'ABC')
UNION
SELECT *
FROM SomeTable
Where
NOT EXISTS (Select spName From SomeOtherTable Where spName = 'ABC')
The UNION will effectivly split this into two simpler queries which can be optiomised separately (depends very much on DBMS, table size etc whether this will actually improve performance -- but its always worth a try).
The "EXISTS" key word is more efficient than the "SELECT COUNT(1)" as it will return true as soon as the first row is encountered.
Or check if the value exists in db first
And you can remove the distinct keyword in your query, it is useless here.
if EXISTS (Select spName From SomeOtherTable Where spName = 'ABC')
begin
SELECT *
FROM SomeTable
WHERE
SomeTable.ID in
(SELECT ID FROM SomeOtherTable Where Name = 'ABC')
end
else
begin
SELECT *
FROM SomeTable
end
Aloha
Try
select t.* from SomeTable t
left outer join SomeOtherTable o
on t.id = o.id
where (not exists (select id from SomeOtherTable where spname = 'adbc')
OR spname = 'adbc')
-Edoode
change all your select statements in the where part to inner jons.
the OR conditions should be union all-ed.
also make sure your indexing is ok.
sometimes it pays to have an intermediate table for temp results to which you can join to.
It seems to me that there is no need for the "1=1 AND" in your query. 1=1 will always evaluate to be true, leaving the software to evaluate the next part... why not just skip the 1=1 and evaluate the juicy part?
I am going to stick to my original Query.