SQL filter rows in table - sql

I'm trying to select rows from a table with the exception of any rows containing 'NEW_' at the beginning. I think I have the logic correct but I am unsure of the syntax. Can anyone help me out?
SELECT *
FROM CUSTOMER e1
WHERE e1.cust_ref LIKE 'CUST_REF%'
AND e1.cust_ref NOT IN (SELECT e2.cust_ref
FROM CUSTOMER e2
WHERE e1.cust_ref = 'NEW_' + e2.cust_ref);

select * from CUSTOMER
WHERE cust_ref like 'CUST_REF%'
AND cust_ref not in
(select cust_ref from sd_filter_element where cust_ref not like 'NEW_%');
You should use like to do this.

If you just want cust refs that don't have "NEW_", why not just do this?
select c.*
from CUSTOMER c
WHERE c.cust_ref not like 'NEW_%' ;

Here is SQL query for filter option
select *
from sd_filter_element
WHERE
cust_ref not like 'NEW_%';

Related

SQL Join and contains

I'm struggling with this query:
SELECT *
FROM Transactions
WHERE CustomerID IN (SELECT ID FROM Customers
WHERE Name LIKE '%Test%')
It takes 10 seconds to run, however if I create the query manually by taking the 4 values returned by the sub query it runs in milliseconds, for example:
SELECT *
FROM Transactions
WHERE (CustomerID = 1 OR CustomerID = 2 OR
CustomerID = 3 OR CustomerID = 4)
To clarify, running
SELECT ID FROM Customers WHERE Name LIKE '%Test%'
returns the values 1,2,3,4 immediately
Any ideas? What am I missing?
As you already said, when you have the customer id's it runs in milliseconds so the filtering of the customer name is the problem.
The first wildcard (WHERE name LIKE '%Test%') is the suspect here because sql server needs to read all the strings in the name column like a regular expression and find if there is any "Test" in there for every row in the table!
If the names you are filtering for would always start with a "Test" and you could do a WHERE name LIKE 'Test%' it would work much better because sql server only needs to read the start of each string.
Edit:
Here is a little bit different version of the original query if you want to try:
SELECT * FROM Transactions t
WHERE EXISTS (
SELECT 1 FROM
Customers c
WHERE c.ID = t.CustomerID
AND c.Name LIKE '%Test%'
)
What happens with a join?
SELECT t.*
FROM Transactions t JOIN
Customers c
ON t.CustomerID = c.ID
WHERE c.Name Like '%Test%';
Sometimes, JOINs optimize better than IN.

query inside like operator

Can I use query inside the like operator.
I used the query below, but it returns error.
select *
from customers
where cust_name like '%'||select name from members||'%'
Something like the following should work :
SELECT
*
FROM
customers c
WHERE 1=1
AND EXISTS
(SELECT 1
FROM members m
WHERE 1=1
AND c.cust_name LIKE '%'||m.name||'%'
)
In PLSQL if you want to run a Query then you need to decalre a variable to hold the result of the query. So you can do it as :
DECLARE
var customers%ROWTYPE;
BEGIN
SELECT c.*
INTO var
FROM customers c
INNER JOIN members m ON c.cust_name LIKE '%' || m.name || '%';
END;
it is sufficient to enclose the subquery in parentheses
like as
cust_name like '%'||(select name from members)||'%'
but this only works when the table "members" has only one record
You should define the name part of members in subselect (works with only 1 row):
select *
from customers
where cust_name like (select '%'||name||'%' from members);
Same can be done with JOIN (works with multiple rows):
select C.*
from customers C
INNER JOIN MEMBERS M ON (C.CUST_NAME LIKE '%'||M.NAME||'%');

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
)

Compare 2 tables and find the missing record

I have 2 database tables:
customers and customers_1
I have 100 customers in the customers table but only 99 customers in the customers_1 table. I would like to write a query that will compare the 2 tables and will result in the missing row.
I have tried this following SQL:
select * from customers c where in (select * from customers_1)
But this will only check for the one table.
Your query shouldn't work this way. You have to compare one column to another and use NOT IN instead of IN:
select *
from customers c
where customerid not in (select customerid from customers_1)
However, Since you are on SQL Server 2008, you can use EXCEPT:
SELECT * FROM customers
EXCEPT
SELECT * FROM customers_1;
This will give you the rows which are in the customers table that are not in customers_1 table:
EXCEPT returns any distinct values from the left query that are not
also found on the right query.
This is easy. Just join them with a left outer join and check for NULL in the table which has the 99 rows. It will look something like this.
SELECT * FROM customers c
LEFT JOIN customers1 c1 ON c.some_key = c1.some_key
WHERE c1.some_key IS NULL
Instead of NOT IN clause consider using NOT EXISTS. NOT EXISTS clause performs better in this particular scenario. Your query would look like:
SELECT * FROM Customer c WHERE NOT EXISTS (SELECT 1 FROM Customer_1 c1 WHERE c.Customer_Id = c1.Customer_Id)
SELECT 1 is just for readability so everyone will know that I don't care about the actual data.

How to select all columns, and a count(*) in the same query

In often use in TSQL the following query :
SELECT COUNT(*), *
FROM CUSTOMER c
WHERE c.Name like 'foo%';
When I try to execute this query in Oracle SQL Developer it doesn't work and throws me an error:
"Missing expression"
What is the good syntax ?
Thanks in advance.
This will perform better:
SELECT COUNT(*) OVER (), c.*
FROM CUSTOMER c
WHERE c.Name like 'foo%';
One approach is to do something like the following. This will result in a count(*) result for each line. But beware, there is a Cartesianjoin; if you have many rows like 'foo%' this will perform badly.
select a.cntr, c.*
from CUSTOMER c
, (select count(*) cntr
from customer b
where b.name like 'foo%' ) a
where c.name like 'foo%'
here below MySQL code is the way to get both select * from and total rows returned in a single query.
$result = $db->get_results("SELECT a.total, c.* FROM tableName c,
(select count(*) total from tableName b where b.post=25) a
where c.post=25");
then you can get variable total to get count, and * can use for based on your table column.
But how to get the total without foreach() or directly into a vaiable?
I go it total without foreach Here:
echo "Total: ".count($result);