Nested SELECT vs JOIN performance [closed] - sql

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 8 months ago.
Improve this question
I have the following two tables in PostgreSQL database (simplified for the sake of example):
article
id
summary
1
Article 1
2
Article 2
3
Article 3
...
...
event
id
article_id
eventtype_id
comment
108
1
4
Comment 1
109
2
8
Comment 2
110
3
4
Comment 3
...
...
I would like to select only 1 event with eventtype_id=4 for each article. The result should look like this:
article_id
article_summary
event_comment
1
Article 1
Comment 1
2
Article 2
3
Article 3
Comment 3
...
Which of these 2 queries (Query 1 or Query 2) runs faster? Do they return the same result?
Query1:
SELECT
a.id AS article_id,
a.summary AS article_summary,
evnt.comment AS event_comment
FROM
article a
LEFT JOIN
event evnt ON evnt.article_id = a.id AND evnt.eventtype_id = 4;
Query2:
SELECT
a.id AS article_id,
a.summary AS article_summary,
(
SELECT
evnt.comment
FROM
event evnt
WHERE
evnt.article_id = a.id AND
evnt.eventtype_id = 4
LIMIT 1
) AS event_comment
FROM
article a;

Apart from the fact that queries are not the same, as you said in the comments, generally speaking, correlated queries are not considered suitable from a performance point of view. That's because these queries are applied row by row. They are usually helpful in some particular situations: read this. However, even in those situations, it is a good practice to use them in an exists clause if possible, So that whenever it finds a row for the query it returns true.

Related

SQL QUERY SQL SSRS [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Hi can anyone help me with sum up first two rows in table and then rest would be same. example is
ID SUM
12 60
0 20
1 30
2 50
3 60
I am expecting
ID SUM
0 80
1 30
2 50
3 60
I am doing this from memory - so if this doesnt work let me know and we can do it another way looking at the row number;
Assuming you have a unique ID to sort it by as you suggested, you could do something like this;
you may want to change the order to be desc if that's how you classify your 'top 2'
SELECT TOP 2 ID,
SUM(VALUE)
FROM [Table]
GROUP BY ID
ORDER BY ID
UNION
SELECT ID,
VALUE
FROM [Table]
WHERE ID NOT IN (SELECT TOP 2 ID
FROM [Table] ORDER BY ID)

MS Access SQL - Average of 3 Previous Rows [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 have a column of values where I need to take the average of the two previous values and the current value and display as a new column. I'm using MS Access 2013 and am more familier using SQL code rather than the SQL Query Wizard. So, if you could provide the code I'd appreciate it.
I've read on other threads that talked about a Lag function, but I believe Access does not allow that. Also, I've seen similar questions answered with subqueries, but I'm not familiar enough with those yet.
Below is what I'm looking for. Given column A (1,2,3,4,5) how do I make B (0,0,2,3,4)?
A | B
----------
1 | 0
2 | 0
3 | 2 = (1+2+3)/3
4 | 3 = (2+3+4)/3
5 | 4 = (3+4+5)/3
Utilize a self join to the same table for when the value of A is BETWEEN a - 2 and A.
SELECT
t.A
,SUM(pre.A) / 3 as B
FROM
TableName t
LEFT JOIN TableName pre
ON pre.A >= (t.A - 2)
AND pre.A <= t.A
GROUP BY
t.A
Note that this will actually give you 0,1,2,3,4. If you want 0,0,2,3,4 you will have to count the preceding rows to determine if there are three and if not make it 0 such as:
SELECT
t.A
,IIF(COUNT(pre.A) < 3, 0, SUM(pre.A) / 3) as B
FROM
TableName t
LEFT JOIN TableName pre
ON pre.A >= (t.A - 2)
AND pre.A <= t.A
GROUP BY
t.A

Oracle SQL : Union and Joins [closed]

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 8 years ago.
Improve this question
I have a table ACCPLAN(PRIMARY KEY : ACCOUNT_ID)
ACCOUNT_ID PLAN_TYPE OTHER_STUFF
ACC1 PLAN_TYPE_ONE ....
ACC2 PLAN_TYPE_TWO ....
ACC3 PLAN_TYPE_ONE ....
ACC4 PLAN_TYPE_TWO ...
I have one more table ACCTRANSACTION (PRIMARY KEY -> (ACCOUNT_ID,TRANSACTION_ID)
ACCOUNT_ID TRANSACTION_ID TRANSACTION_AMOUNT TXN_TYPE
ACC1 1 100 TXN_TYPE_1
ACC1 2 300 TXN_TYPE_2
ACC2 1 400 TXN_TYPE_2
ACC3 1 400 TXN_TYPE_3
There are 5 fixed plan_types and 20 fixed txn_types.Only few transactions types are
possible for each plan_type.(For eg : TXN_TYPE_1 and TXN_TYPE_2 are possible for
PLAN_TYPE_ONE and TXN_TYPE_2 and TXN_TYPE_3 are possible for PLAN_TYPE_TWO)
I am trying to retrieve the transaction information from ACCTRANSACTION and other
details from ACCPLAN
This can be done in 2 ways
APPROACH 1
Retrieve for each plan_type and do an union
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and ap.plan_type = PLAN_TYPE_ONE
and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2);
union
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and ap.plan_type = PLAN_TYPE_TWO
and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3);
union
...
APPROACH 2
Retrieve using one query for all plan_types
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id = at.account_id
and
((ap.plan_type = PLAN_TYPE_ONE and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2))
or
(ap.plan_type = PLAN_TYPE_TWO and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3));
which approach is better considering both tables have huge data?. Please suggest.
Use joins. Unions require sorting the whole result and it is an expensive operation for your database.
Furthermore. It is better to read the table one time and do some complex checks with each record than reading it several times just to make smaller checks.
Disclaimer: I can imagine some very strange corner cases where the first query runs faster if the database query planner decides that the big condition is not selective enough and does not uses an index and each of the smaller one does use it. The bigger the number of rows the more I would use the second option.

Select simplest element SQL Server recursion changed complexity of table [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 9 years ago.
Improve this question
I have T1 table with Id and name columns.
Table T2 with Aggregate_ID and Element_ID.
They are crossed
x1:
ID и Name
1 Car
2 Hood
3 Engine
4 Cylinder
5 Wheel
6 tyre
7 rim (car)
8 Rim fixation (Car)
x2:
Aggregate_ID Element_ID
1 2
1 3
1 4
1 5
3 4
5 6
5 7
7 8
I need to select simplest element like 2, 4, 8
Complexity and number of elements can be varied.
How can I do it with recursion?
There is another task:
I need to output all the simplest elements of which consists Wheel.
Recursive solution in SQL can be very complex. In your case I see no need to use it, since it will only make your code more complex.
You can use CTE if you still insist:
Recursive query in SQL Server
Non- recursive solution:,
You want only the elements that appear in T2 in the Element_ID but not in the Aggregate_ID:
SELECT Element_ID
FROM T2
EXCEPT
SELECT Aggregate_ID
FROM T2
Or if you want to display all of the information for the elements:
SELECT *
FROM T1
WHERE T1.ID NOT IN (SELECT Aggregate_ID
FROM T2)

Oracle SQL How to find missing value for different users

I have 2 tables
One table with questions
ID Description
== ===========
1 Some Question
2 Some Question
3 Some Question
4 Some Question
And an other one with the awsers to each question of every users
ID_USER ID_QUESTION ANSWER
======= =========== =========
1 2 a
1 1 b
1 3 d
2 1 e
2 4 a
3 4 c
3 2 a
As you can see it is possible that a user does not answer a question and this is my problem
I am currently trying to find wich answer a user did not answer to.
I'd like to have something like this
ID_USER ID_MISSING_QUESTION
======= ===================
1 4
2 3
2 2
3 1
3 3
I can easly find the missing questions for a single user but i can't do that for every user since they are quite numerous.
Thanks Ayoye
Quick and Dirty:
SELECT TB_USER.ID, TB_QUESTION.ID AS "Q_ID" FROM TB_USER, TB_QUESTION
minus
SELECT ID_USER, ID_QUESTION FROM tb_answer
Sql Fiddle Demo here.
I think You are looking for something like this:
SELECT
u.id_user,
q.id_question
FROM
questions q
CROSS JOIN users u
LEFT JOIN answers a ON (a.id_question = q.id_question and a.id_user = u.id_user)
WHERE
a.answer IS NULL
First You shoyul create set of every question for every user, and then try to join in with Your answers. And then filer out all results that have found answers. :)
You should post the SQL statement(s) you tried, before expecting a full answer, else someone might think you want let others write all the code for you...
Nevertheless, instead of plain JOIN, use a FULL OUTER JOIN and a LEFT OUTER JOIN resp. RIGHT OUTER JOIN, depending on table ordering in your SQL statement (which you did not post yet), and filter with IS NULL.