sql query get Data on pre conditions [closed] - sql

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 5 years ago.
Improve this question
i need fruit list which price greater than in tableA for each fruit.
ID | fruit | Price
----------------------------
1 | apple | 10
2 | banana| 7
3 | grapes| 6
then i have daily table like below
ID | fruit | Price
----------------------------
1 | apple | 9
2 | banana| 5
3 | grapes| 9
4 | mango | 15
in this condition i get only grapes

I think you can just join the daily and tableA tables on the fruit's ID, and then compare prices.
SELECT t1.*
FROM daily t1
INNER JOIN tableA t2
ON t1.ID = t2.ID
WHERE t1.price > t2.price
Note that we join on the ID rather than the fruit name, since in theory names may not be completely unique across a very large table of fruits.

just join by ID and add your additional condition (price in tableA is greater than price in dailyTable).
you don't need to join by column fruit - but if so, it won't change your resultset.
SELECT TableA.*, dailyTable.Price
FROM TableA
INNER JOIN dailyTable
ON TableA.ID = dailyTable.ID
AND TableA.Price > dailyTable.Price
the column fruit is redundant data. so you shouldn't store it in the daily table.

Related

Complex SQL Joins with Where Clauses

Being pretty new to SQL, I ask for your patience. I have been banging my head trying to figure out how to create this VIEW by joining 3 tables. I am going to use mock tables, etc to keep this very simple. So that I can try to understand the answer - no just copy and paste.
ICS_Supplies:
Supplies_ ID Item_Description
-------------------------------------
1 | PaperClips
2 | Rubber Bands
3 | Stamps
4 | Staples
ICS_Orders:
ID SuppliesID RequisitionNumber
----------------------------------------------------
1 | 1 | R1234a
6 | 4 | R1234a
2 | 1 | P2345b
3 | 2 | P3456c
4 | 3 | R4567d
5 | 4 | P5678e
ICS_Transactions:
ID RequsitionNumber OrigDate TransType OpenClosed
------------------------------------------------------------------
1 | R1234a | 06/12/20 | Req | Open
2 | P2345b | 07/09/20 | PO | Open
3 | P3456c | 07/14/20 | PO | Closed
4 | R4567d | 08/22/20 | Req | Open
5 | P5678e | 11/11/20 | PO | Open
And this is what I want to see in my View Results
Supplies_ID Item RequsitionNumber OriginalDate TransType OpenClosed
---------------------------------------------------------------------------------------
1 | Paper Clips | P2345b | 07/09/20 | PO | OPEN
2 | Rubber Bands | Null | Null | Null | Null
3 | Stamps | Null | Null | Null | Null
4 | Staples | P56783 | 11/11/20 | PO | OPEN
I just can't get there. I want to always have the same amount of records that we have in the ICS_Supplies Table. I need to join to the ICS_Orders Table in order to grab the Requisition Number because that's what I need to join on the ICS_Transactions Table. I don't want to see data in the new added fields UNLESS ICS_Transactions.TransType = 'PO' AND ICS_Transactions.OpenClosed = 'OPEN', otherwise the joined fields should be seen as null, regardless to what they contain. IF that is possible?
My research shows this is probably a LEFT Join, which is very new to me. I had made many attempts on my own, and then posted my question yesterday. But I was struggling to ask the correct question and it was recommended by other members that I post the question again . .
If needed, I can share what I have done, but I fear it will make things overly confusing as I was going in the wrong direction.
I am adding a link to the original question, for those that need some background info
Original Question
If there is any additional information needed, just ask. I do apologize in advance if I have left out any needed details.
This is a bit tricky, because you want to exclude rows in the second table depending on whether there is a match in the third table - so two left joins are not what you are after.
I think this implements the logic you want:
select s.supplies_id, s.item_description,
t.requisition_number, t.original_date, t.trans_type, t.open_closed
from ics_supplies s
left join ics_transaction t
on t.transtype = 'PO'
and t.open_closed = 'Open'
and exists (
select 1
from ics_order o
where o.supplies_id = s.supplies_id and o.requisition_number = t.requisition_number
)
Another way to phrase this would be an inner join in a subquery, then a left join:
select s.supplies_id, s.item_description,
t.requisition_number, t.original_date, t.trans_type, t.open_closed
from ics_supplies s
left join (
select o.supplies_id, t.*
from ics_order o
inner join ics_transaction t
on t.requisition_number = o.requisition_number
where t.transtype = 'PO' and t.open_closed = 'Open'
) t on t.supplies_id = s.supplies_id
This query should return the data for supplies. The left join will add in all orders that have a supply_id (and return null for the orders that don't).
select
s.supplies_id
,s.Item_Description as [Item]
,t.RequisitionNumber
,t.OrigDate as [OriginalDate]
,t.TransType
,t.OpenClosed
from ICS_Supplies s
left join ICS_Orders o on o.supplies_id = s.supplies_id
left join ICS_Transactions t on t.RequisitionNumber = o.RequisitionNumber
where t.TransType = 'PO'
and t.OpenClosed = 'Open'
The null values will automatically show null if the record doesn't exist. For example, you are joining to the Transactions table and if there isn't a transaction_id for that supply then it will return 'null'.
Modify your query, run it, then maybe update your question using real examples if it's possible.
In the original question you wrote:
"I only need ONE matching record from the ICS_Transactions Table.
Ideally, the one that I want is the most current
'ICS_Transactions.OriginalDate'."
So the goal is to get the most recent transaction for which the TransType is 'PO' and OpenClosed is 'Open'. That the purpose of the CTE 'oa_cte' in this code. The appropriate transactions are then LEFT JOIN'ed on SuppliesId. Something like this
with oa_cte(SuppliesId, RequsitionNumber, OriginalDate,
TransType, OpenClosed, RowNum) as (
select o.SuppliesId, o.RequsitionNumber,
t.OrigDate, t.TransType, t.OpenClosed,
row_number() over (partition by o.SuppliesId
order by t.OrigDate desc)
from ICS_Orders o
join ICS_Transactions t on o.RequisitionNumber=t.RequisitionNumber
where t.TransType='PO'
and t.OpenClosed='OPEN')
select s.*, oa.*
from ICS_Supplies s
left join oa_cte oa on s.SuppliesId=oa.SuppliesId
and oa.RowNum=1;

Database Design question best way to solve this issue [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 3 years ago.
Improve this question
I'm kind of new in database design and I'm trying to find the best way to solve an issue I'm facing.
Let's think about the following example:
Imagine I want to store information about patients and these patients can have 0+ diseases.
What's the best way of storing arranging the tables to display the diseases that each patient can have? I get confused as to what happens when a patient would have 3 diseases; how is this stored in a relational database? e.g. without having repeated rows on the diseases table for example (static number of diseases)..
I'm not sure if I'm making myself totally clear here!
But let's say I don't think it's efficient to have:
Patient table -
Patient_id , disease_id
1, (3,4,5,6)
Any help is appreciated!
As mentioned in the comments, you would use an associative entity for that.
Let say you have the following diseases:
| Disease_id | Disease_name |
-----------------------------
| 1 | Cancer |
-----------------------------
| 2 | Leucemia |
-----------------------------
Your patients may look like this
| Patient_id | Patient_name |
-----------------------------
| 1 | Peter Jones |
-----------------------------
| 2 | Mark Jacobs |
-----------------------------
You now create a table like so (lets call it ill_patients)
| Patient_id | Disease_id |
---------------------------
| 1 | 1 |
---------------------------
| 1 | 2 |
---------------------------
This would mean that poor Peter Jones has cancer as well as leucemia. You can now query your patient table like so:
SELECT patients.patient_name, diseases.disease_name
FROM (diseases INNER JOIN ill_patients ON diseases.disease_id = ill_patients.disease_id) INNER JOIN patients ON ill_patients.patient_id = patients.patient_id;
This gives you all the patients with their respective diseaes.
Patients:
patient_id, name, phone
Disease:
disease_id, name, description
Patient_Disease:
patient_id, disease_id
Example:
patient_id, name , phone
1 , 'jhon', '555-1234'
disease_id, name , description
1 , 'Cancer' , 'Cancer is the uncontrolled development of cells.'
2 , 'Diabetes', 'Diabetes is a disease that occurs when your blood glucose is too high.'
patient_id, disease_id
1 , 1
1 , 2
Then you can do
SELECT p.name, d.name, d.description
FROM patients p
JOIN patient_disease pd
ON p.patient_id = pd.patient_id
JOIN diseases d
ON pd.disease_id = d.disease_id

Joining two tables where one contains multiple rows that refer to one row in the other table PSQL

So I have two tables that look like this:
nalog:
prod_num
id
qa_stavka_kontrola:
status
id_nalog
id
redak --question id
The second table is used to store yes or no answers (in column status(boolean)) about books that are contained in the first table. Multiple rows of the second table refer to one row in the first one. I want to make a report that looks something like this:
|prod_num | question 1 | question 2 | question 3 |
|52 | 1 | 0 | 1 |
|53 | 0 | 1 | 1 |
This is my query but it is very very slow:
select nalog.prod_num
, r1.status as question1
, r2.status as question2
, r3.status as question3
from nalog
left join qa_stavka_kontrola as r1
on nalog.id=r1.id_nalog and r1.redak=1 and (r1.status=1 or r1.status=0)
left join qa_stavka_kontrola as r2
on nalog.id=r2.id_nalog and r2.redak=2 and (r2.status=1 or r2.status=0)
left join qa_stavka_kontrola as r3
on nalog.id=r3.id_nalog and r3.redak=3 and (r3.status=1 or3.status=0)
where nalog.date BETWEEN '2017-09-01' and '2018-01-11'
group by nalog.prod_num, r1.status, r2.status, r3.status
I might be off, but you can try to use PIVOT, check documentation for more info.
with something as
(select t1.prod_num, t2.redak
from nalog t1
left outer join qa_stavka_kontrola t2
on t1.id=t2.id_nalog
where t2.status in (0,1)
and t1.date BETWEEN '2017-09-01' and '2018-01-11' -- is there a date column?
)
select *
from something
pivot (count(redak) for redak in (1 as question_1, 2 as question_2, 3 as question_3));

Add counter field in select result in Access Query [duplicate]

This question already has an answer here:
Access query producing results like ROW_NUMBER() in T-SQL
(1 answer)
Closed 8 years ago.
I have a table with some field.
name, stud_id
ali | 100
has | 230
mah | 300
I want to get some of record and show a row field beside of record.
1 | ali | 100
2 | has | 230
3 | mah | 300
How I can do it.
Thanks.
Select (select count(*) from Table1 A where A.stud_id>=B.stud_id) as RowNo, B.*
from Table1 as B
order by A.stud_id
MS-ACCESS does not have rownum function, so this might help you.
But your ID need to be sortable and unique.

Summarizing three variables using sql [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
Here is the raw data
Book | Author | Year
A | A1 | 1985
A | B1 | 1985
B | A1 | 1988
B | C1 | 1988
D | A1 | 1990
D | C1 | 1990
D | B1 | 1990
Here is what output I am looking for,
Author1 | Author2 | year | count
A1 | B1 | 1985 | 1
A1 | C1 | 1985 | 1
A1 | C1 | 1988 | 1
A1 | B1 | 1990 | 1
A1 | C1 | 1990 | 1
B1 | C1 | 1990 | 1
Any help is deeply appreciated.
Thanks
The query you are looking for is a self join with an aggregation:
select t1.author as author1, t2.author as author2, t1.year, count(*) as `count`
from t t1 join
t t2
on t1.book = t2.book and
t1.author < t2.author
group by t1.author, t2.author, t1.year
order by t1.author, year;
SELECT A.author AS author1,
B.author AS author2,
A.year,
COUNT(*) AS "count"
FROM Author A
LEFT JOIN Author B
ON B.book = A.Book
AND B.author > A.Author
GROUP BY A.author, B.author, A.year
ORDER BY A.author, B.author, A.year
This will work okay only as long as there are no more than two rows per book in your Author table. Otherwise, it will produce multiple lines per book. If that is possibly the case, you should indicate what flavor of SQL should be used, as the means to limit the results from Table B differ from implementation to implementation. I have arbitrarily chosen to list the authors in alphabetical order, since there appears to be no indicator of which author is "primary."
I would hope that there are come additional columns in the table that you are not telling us about--most specifically a primary key, and perhaps some attribute indicating the "billing order" of the authors with respect to a given book.
You might want to reconsider your table design, if that's possible: it's in a non-normalized form that makes data integrity hard to enforce.