T-SQL : check if data exists in table - sql

I am using a view that checks if data exists in another table and if it exists if shows the number of row's connected to that table. Now I was wondering if there might be a faster way of doing this, since I am only interested if there is data and not necessary how many data rows there are. I guess when it does not need to count it will be faster.
This is what I use now:
SELECT
dbo.user.id,
dbo.user.userCode,
COALESCE (TotalProducts.ProductsInback, 0) AS ProductsInback
FROM
dbo.user
LEFT OUTER JOIN
(SELECT COUNT(id_product) AS ProductsInback, userCode
FROM dbo.Product
GROUP BY userCode) AS TotalProducts ON dbo.Product.userCode = TotalProducts.userCode
WHERE
dbo.user.userCode = 'XYZ'
Now this works all fine an it gives me the number of products connected to the user XYZ that are in the back of the store. However I just want to know if the user has products in the back of the store, I don't need to know how many. That seems to me a faster solution (walking anyway to the back of the store). So replacing the COUNT with ... ?

You are right, for a lookup whether data exists in another table, we use EXISTS or IN, because we don't have to go through all matching rows then, but can stop at the first one found.
EXISTS:
SELECT
id,
userCode,
CASE WHEN EXISTS (SELECT * FROM dbo.Product p WHERE p.userCode = u.userCode )
THEN 1 ELSE 0 END AS ProductsInback
FROM dbo.user u
WHERE u.userCode = 'XYZ'
IN:
SELECT
id,
userCode,
CASE WHEN userCode IN (SELECT userCode FROM dbo.Product)
THEN 1 ELSE 0 END AS ProductsInback
FROM dbo.user
WHERE userCode = 'XYZ'

If you change your left join to an inner join, you will just get a list of users with products. The other users will not appear on the list.
SELECT
dbo.user.id,
dbo.user.userCode
FROM dbo.user
JOIN dbo.Product
ON dbo.Product.userCode= TotalProducts.userCode

Related

Remove duplicates from result in sql

i have following sql in java project:
select distinct * from drivers inner join licenses on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false
And result i database looks like this:
And i would like to get only one result instead of two duplicated results.
How can i do that?
Solution 1 - That's Because one of data has duplicate value write distinct keyword with only column you want like this
Select distinct id, distinct creation_date, distinct modification_date from
YourTable
Solution 2 - apply distinct only on ID and once you get id you can get all data using in query
select * from yourtable where id in (select distinct id from drivers inner join
licenses
on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false )
Enum fields name on select, using COALESCE for fields which value is null.
usually you dont query distinct with * (all columns), because it means if one column has the same value but the rest isn't, it will be treated as a different rows. so you have to distinct only the column you want to, then get the data
I suspect that you want left joins like this:
select *
from users u left join
drivers d
on d.user_id = u.id and d.status = 'WAITING' left join
licenses l
on d.user_id = l.issuer_id and l.state = 'ISSUED'
where u.is_deleted = false and
(d.user_id is not null or l.issuer_id is not null);

Select Combination of columns from Table A not in Table B

I have two sets of table with all the contacts on an Account their titles and etc. For data migration purposes I need to select All ContactsIds with their AccountID from Table A that do not exist in TableB. Its the combination of both the ContactId and the AccountID. I have tried the following:
Select * from Final_Combined_Result wfcr
WHERE NOT EXISTS (Select Contact_ID, Account_ID from Temp_WFCR)
I know this is completely off, but I have looked at a couple of other questions on here but was unable to find an appropriate solution.
I have also tried this:
Select * from Final_Combined_Result wfcr
WHERE NOT EXISTS
(Select Contact_ID, Account_ID from Temp_WFCR as tc
where tc.Account_ID=wfcr.Account_InternalID
AND tc.Account_ID=wfcr.Contact_InternalID)
This seems to be correct but I would like to make sure.
Select wfcr.ContactsId, wfcr.AccountID
from Final_Combined_Result wfcr
left join Temp_WFCR t_wfcr ON t_wfcr.ContactsIds = wfcr.ContactsId
AND t_wfcr.AccountID = wfcr.AccountID
WHERE t_wfcr.AccountID is null
See this great explanation of joins
#juergend's answer shows the left join.
Using a not exists you join in the subselect, it would look like this:
Select wfcr.*
from
Final_Combined_Result wfcr
WHERE NOT EXISTS
(Select 1 --select values dont matter here, only the join restricts.
from
Temp_WFCR t
where t.Contact_ID = wfcr.Contact_InternalID
and t.account_id = wfcr.Account_InternalID
)

Trouble with tsql not in query

I'm trying to find rows where a value in table 1 column A are not in table 2 column A
This is the query...
SELECT contactsid
FROM contacts
WHERE (email1 NOT IN (SELECT email
FROM old_contact))
It returns 0 rows, which I know is incorrect. There are many rows in contacts.email1 that are not in old_contact.email
How should I be writing this query?
My guess is that old_contract.email takes on a NULL value.
For this reason, not exists is often a better choice:
SELECT contactsid
FROM contacts c
WHERE NOT EXISTS (SELECT 1
FROM old_contract oc
WHERE c.email = oc.email1
) ;
You could also add where email1 is not null to the subquery. However, I find just using not exists is generally safer in case I forget that condition.
Try:
SELECT contactsid
FROM Contacts a
LEFT JOIN old_contact b
ON a.email1 = b.email
WHERE b.email IS NULL
This will join Contacts to old_contact using a LEFT JOIN -- a type of join that, based on the join condition, returns all records from the left side (i.e. Contacts) even if no records exist on the right side. Then, the WHERE clause filters the results so that it returns only the records from the left side where the ride side records don't exist.

Update using Distinct SUM

I have found a few good resources that show I should be able to merge a select query with an update, but I just can't get my head around of the correct formatting.
I have a select statement that is getting info for me, and I want to pretty much use those results to Update an account table that matches the accountID in the select query.
Here is the select statement:
SELECT DISTINCT SUM(b.workers)*tt.mealTax as MealCost,b.townID,b.accountID
FROM buildings AS b
INNER JOIN town_tax AS tt ON tt.townID = b.townID
GROUP BY b.townID,b.accountID
So in short I want the above query to be merged with:
UPDATE accounts AS a
SET a.wealth = a.wealth - MealCost
Where MealCost is the result from the select query. I am sure there is a way to put this into one, I just haven't quite been able to connect the dots to get it to run consistently without separating into two queries.
First, you don't need the distinct when you have a group by.
Second, how do you intend to link the two results? The SELECT query is returning multiple rows per account (one for each town). Presumably, the accounts table has only one row. Let's say that you wanted the average MealCost for the update.
The select query to get this is:
SELECT accountID, avg(MealCost) as avg_Mealcost
FROM (SELECT SUM(b.workers)*tt.mealTax as MealCost, b.townID, b.accountID
FROM buildings AS b INNER JOIN
town_tax AS tt
ON tt.townID = b.townID
GROUP BY b.townID,b.accountID
) a
GROUP BY accountID
Now, to put this into an update, you can use syntax like the following:
UPDATE accounts
set accounts.wealth = accounts.wealth + asum.avg_mealcost
from (SELECT accountID, avg(MealCost) as avg_Mealcost
FROM (SELECT SUM(b.workers)*tt.mealTax as MealCost, b.townID, b.accountID
FROM buildings AS b INNER JOIN
town_tax AS tt
ON tt.townID = b.townID
GROUP BY b.townID,b.accountID
) a
GROUP BY accountID
) asum
where accounts.accountid = asum.accountid
This uses SQL Server syntax, which I believe is the same as for Oracle and most other databases. Mysql puts the "from" clause before the "set" and allows an alias on "update accounts".

how can i eliminate duplicates in gridview?

i am retrieving data from three tables for my requirement so i wrote the following query
i was getting correct result but the problem is records are repeated whats the problem in
that query. i am binding result of query to grid view control. please help me
SELECT DISTINCT (tc.coursename), ur.username, uc. DATE, 'Paid' AS Status
FROM tblcourse tc, tblusereg ur, dbo.UserCourse uc
WHERE tc.courseid IN (SELECT ur1.courseid
FROM dbo.UserCourse ur1
WHERE ur1.userid = #userid)
AND ur.userid = #userid
AND uc. DATE IS NOT NULL
AND ur.course - id = uc.course - id
There is no JOIN between tblcourse tc,tblusereg ur. So you get a cross join despite the IN (which is actually a JOIN)
DISTINCT works on the whole row too: not one column.
Note: you mention dbo.UserCourse twice but use different column names courseid and [course-id]
Rewritten with JOINs.
select distinct
tc.coursename, ur.username, uc.[date], 'Paid' as [Status]
from
dbo.tblcourse tc
JOIN
dbo.tblusereg ur ON tc.courseid = ur.[course-id]
JOIN
dbo.UserCourse uc ON ur.[course-id] = uc.[course-id]
where
ur.userid=#userid
and
uc.[date] is not null
This may fix your problem...
Change that first part of your query
select distinct (tc.coursename),
TO
select distinct tc.coursename,
to make all the columns distinct not just tc.coursename