Sql performance query multiple conditions on same column [closed] - sql

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I have a table ORDERS with ORDER_ID and SERVICE_ID field.
I can have multiple entries in table like:
ID ORDER_ID SERVICE_ID
1 000001 1
2 000001 2
3 000001 3
4 000002 1
5 000002 2
I need to final all orders that have entries for service_id 2 but not for service_id 3.
My query is:
SELECT * FROM ORDERS
WHERE SERVICE_ID = 2
AND ORDER_ID NOT IN (SELECT ORDER_ID FROM ORDERS WHERE SERVICE_ID = 3)
Is there another way to do this in order to improve performance?
Thanx

Use NOT EXISTS which generally performs better than NOT IN:
SELECT * FROM ORDERS O
WHERE O.SERVICE_ID = 2
AND NOT EXISTS
(SELECT 1 FROM ORDERS OO WHERE OO.ORDER_ID = O.ORDER_ID AND OO.SERVICE_ID = 3)

Another way to achieve this would be
select * from orders o1
where service_id = 2
and not exists (
select * from orders o2
where o1.order_id = o2.order_id
and o2. service_id = 3)
But no one will be able to tell you whether any of these will give performance problems due to the following:
As long as your data volume is small, performance will be good no matter how your query is written.
When your query needs optimization, the DBMS optimizer will try to do its best. You can find out what it did and whether it suggests improvements using its "explain" feature (that's what it's called in MS SQL Server, might have a different name for your DBMS) on the actual query on the actual data.
One way to optimize performance is to introduce an index for each attribute (combination) used as selection criteria. In your case that would be order_id and service-id.
Defining a few indexes isn't much work, so you might do it right beforehand. As for other precautions, I would wait until performance issues really turn up, which will probably never happen.

Related

SQL Server : make use of foreign key [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have 2 tables Product and Vendors. In my Product table, I have a primary key and one foreign key VendorID which references the primary key of the Vendors table:
So, what I was trying to do is to determine which products have a quantity of less than 1000 then display the product's vendor ID and name.
I tried doing this:
SELECT VendorID, Name
FROM Vendors, Product
WHERE Quantity < 1000;
but I get an error
Ambiguous column name 'VendorID'
This is the only solution I can think of since I am just only a beginner in using SQL
I think the output must go like this
VendorID Name
--------------------------------------------
V00002 Liwayway Marketing Corporation 8
V00003 Monde Nissin
Try this:
USE myDB;
SELECT v.VendorID, v.Name
FROM Vendors v JOIN Product p
ON v.VendorID = p.VendorID
WHERE p.Quantity < 1000;
It is happening because your program doesn't know which Vendors or Product table to choose from.
I would try to make a union, like NATURAL JOIN which will make your tables "combine", else, you will get every row of Vendors paired with every row of Product.
Plus: the tables are different, so you have to "pair" them so you can use attributes from the two of them.

sql generate group on related groups [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Sorry, if question unclear, i had misstakes it first tables. I made some updates:
Database: PostgreSQL
I want to group table based on transition (if a=b & b=c then a=c)
Adding a pair (4,c) will merge 2 groups to one "group1".
i assume u want a.b.c to be group1 and the d as group2..
the groupby will work perfectly fine with aliases..
but the number of group op wants is 3 millions groups so a stored proc with a incremental in the end and group by will work fine..
From your comments, it looks like you want to find out transitive relationship.
You can do that with following query. But if the goal here is just to identify the relationship among different groups with their respective id, i guess you can afford to have groups which are not getting incremented with 1.
According to your given example in OP, i think it won't affect you if end result has group1 and group5 instead of group2.
If mention result is fine then you can do that with following updated query. Giving group names in successive manner will impact on query performance which you don't want as you've 3 million of groups.
Please try following query:
select t1.id, concat('group', min(t2.minId)) groups
from t1
join
(select min(id) minId, groups
from t1
group by groups
) t2
on t1.groups = t2.groups
join (select #cnt := 1)y
group by t1.id;
Demo : Click here

SQL Server Temp Table to a Select Distinct Count Distinct quetsion [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Ok, basically I've got a lot of temp tables I've created and I'm trying to create Validation for the ProvDiff table.
DROP TABLE #ProvDiff;
IF OBJECT_ID ('temp.dbo.#ProvDiff') IS NOT NULL
DROP TABLE #ProvDiff;
SELECT *
INTO #ProvDiff
FROM
(SELECT DISTINCT *
FROM #finalclaimswithflags f
WHERE f.[Pay-To Prov NPI] <> f.[Rendering Prov NPI]) ProvDiff;
SELECT DISTINCT COUNT(DISTINCT ???) AS 'Unique EI NPIS'
FROM #ProvDiff
In my head it seems like the differences should be able to produce a result and I should be able to do a count on that. But for the life of me I can't figure out how to do that. If I do a count on rendering or pay to then those numbers wouldn't necessarily reflect the value for what are above. I know how many of each are produced for above validation.
Any help would be greatly appreciated
Is this what you want?
SELECT COUNT(*)
FROM (SELECT DISTINCT *
FROM #finalclaimswithflags f
WHERE f.[Pay-To Prov NPI] <> f.[Rendering Prov NPI]
) ProvDiff;
I don't see why a temporary table would be used for this.
For better or worse, SQL Server does not support select count(distinct *), so you pretty much need a subquery.

Need some assistance with 2 SQL queries [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I need some help with my exam, there are 2 questions but I don't know how to join them and which SQL statements I need.
Write a SQL statement which displays the employee id, last name,and salary of any employee whose salary is above the price of the most expensive product.
Write a SQL statement which displays the customer id of customers who purchased the product with product_id 1 but so far never purchased the product with product_id 3.
It would be nice if somebody explain me the solution.
With the understanding this is a practice exam, and that you don't have access to the tables/values....
You really should show what you've tried... but since you're new...
Question 1:
Return employeeID, last name and salary of all employees who have a salary greater than the price of the most expensive product (like how they avoided using the word max there...)
So this uses a subquery to get the max price from products and simply compares salary against it.
SELECT Employee_ID, Last_Name, Salary
FROM employees
WHERE salary > (Select max(price) from Products);
Question 2:
Generate two sets one for product_ID of 1 one for product_ID of 3 and make sure those with 1 are not in the group with 3.
and this uses a correlated subquery (notice how the PUR alias is in the subquery? that's why it's correlated)
So the first query gets all the customers buying product 1. The 2nd query finds all the customers buying product 3. and since we want only those customers who bought 1 not 3, we correlate the queries using not exists and we have our answer.
Exists - usually fastest as it can early exit the subquery once a single record for a customer is found.
SELECT Distinct PUR.Customer_ID
FROM purchases PUR
WHERE PRODUCT_ID = 1
and not exists (SELECT 1
FROM Purchases PUR2
WHERE Product_ID = 3
and PUR.Customer_ID = PUR2.Customer_I
There are 2-3 ways of doing this. I find the above the most efficient in most cases. However you could also do it by... a self join; or using an not IN statement
Self LEFT join (works great if you need data from multiple tables
We self join on purchases but filter each table instance to be for a specific product. we use left join as we want all records with product Id 1 and where a match is found in p2, we want to EXCLUDE those records so if the customer_ID is null that means they have no product 3 purchases
SELECT Distinct P1.customer_ID
FROM Purchases P1
LEFT JOIN Purchase P2
on P1.customer_Id = P2.customer_ID
and P2.Product_ID = 3
WHERE P1.Product_ID = 1
and P2.customer_ID is null
not in (usually slowest but works fine if subquery is for a VERY Small datasets)
SELECT Distinct PUR.Customer_ID
FROM purchases PUR
WHERE PRODUCT_ID = 1
and customer_ID not in (SELECT Customer_Id
FROM Purchases
WHERE Product_ID = 3)
Notice that neither of the 1st two answers uses a join; though a correlated subquery is close.

How to find rows with similar data as a specific row in sql [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Let me make it clear -
I have a table with information such as CourseID, Semester, GPA
I need to find all the CourseID's that have the same GPA(and some more fields) as CourseID='999'
I would also like a solution with AND without nested SELECT
Thanks!
So I have to find all the courseCode that has the same GPA and FailPerc as (Code 999, Year 2011, Sem B, Date 2)
Hope it's more clean now
this might work...
select c1.*
from course c1
inner join course c2 on c1.pga= c2.pga
where c2.courseid = 999
and c1.courseid <> c2.courseid
with subselects
select c1.*
from couser c1
where pga = (select pga
from course c2
where c2.courseid=999)
and c1.courseid <> 999
Before you run any query you need to somehow retrieve the data for the original data row. Unless you're writing your SQL for something like MS Access and can use domain functions like DLOOKUP(), I don't see any other way how you can get this information. This means, you need at least 2 SELECT queries and they must be nested.