I have 3 tables:
Table 1 ExamTB:
ID ExamTerm ExamDate
1 MidTerm 2017-09-24
2 FinalTerm 2017-12-01
Table 2 ExamSubMarksTB
ID ExamID ClassID SubjectID TotalMarks PassMarks
1 1 1 1 100 50
2 1 1 2 100 50
3 1 1 3 100 50
4 2 1 1 100 50
5 2 1 2 100 50
6 2 1 3 100 50
Table 3 ExamResultTB
ID ExamID ClassID SubjectID MarksObtain StdID
1 1 1 1 80 1
2 1 1 2 70 1
3 1 1 3 60 1
4 2 1 1 50 1
5 2 1 2 72 1
6 2 1 3 68 1
Now when I create a Stored Procedure the SELECT this Select Command returns duplicate rows
SELECT ExamResultTB.ExamID
, ExamTB.ExamTerm
, ExamTB.ExamDate
, ExamResultTB.StdID
, StudentTB.Name
, StudentTB.FatherName
, ClassTB.ClassName
, SubjectTB.Subject
, ExamResultTB.ObtainMarks
, ExamSubMarksTB.TotalMarks
, ExamSubMarksTB.PassMarks
FROM ExamResultTB
INNER JOIN ExamTB ON ExamResultTB.ExamID = ExamTB.ID
INNER JOIN ClassTB ON ExamResultTB.ClassID = ClassTB.ID
INNER JOIN SubjectTB ON ExamResultTB.SubjectID = SubjectTB.ID
INNER JOIN StudentTB ON ExamResultTB.StdID = StudentTB.ID
INNER JOIN ExamSubMarksTB ON ExamResultTB.ExamID = ExamSubMarksTB.ExamID
WHERE ExamResultTB.ExamID = 4
AND ExamResultTB.StdID=1
For sure this line make a duplicate row:
INNER JOIN ExamSubMarksTB ON ExamResultTB.ExamID = ExamSubMarksTB.ExamID
You should do it in this way:
INNER JOIN ExamSubMarksTB ON ExamResultTB.ExamID = ExamSubMarksTB.ExamID and
ExamResultTB.ClassId = ExamSubMarksTB.ClassId and ExamResultTB.SubjectID =
ExamSubMarksTB.SubjectID
Related
There are some points and point_types with mark actual:
points
------
id point_type
------
1 1
2 1
3 2
point_types
------
id actual
------
1 true
2 false
Also there are directions:
directions
------
id point_from point_to
------
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 3
7 3 1
8 3 2
9 3 3
I need only directions with actual point_from and point_to:
id point_from point_to
------
1 1 1
2 1 2
4 2 1
5 2 2
Trying with:
SELECT d.id, d.point_from, d.point_to
FROM directions d
JOIN points p ON (d.point_from = p.id OR d.point_to = p.id)
JOIN point_types pt ON pt.id = p.TYPE AND pt.actual = TRUE
GROUP BY 1,2,3
but getting directions with actual point_from or actual point_to :
id point_from point_to
------
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 3
7 3 1
8 3 2
Use a CTE that returns all the ids of the not actual points and then with NOT EXISTS get only the directions that do not contain any of them:
WITH cte AS (
SELECT p.id
FROM points p INNER JOIN point_types pt
ON pt.id = p.point_type
WHERE pt.actual = false
)
SELECT d.*
FROM directions d
WHERE NOT EXISTS (SELECT * FROM cte c WHERE c.id IN (d.point_from, d.point_to));
See the demo.
SubjectMaster
Id Subject
1 English
2 History
3 Maths
UserSubjectAssociation
Id Userid SubjectId
1 1 1
2 1 3
3 2 2
Logs
Id Userid SubjectId Examdate Percentage
1 1 1 02/20/2020 50
2 1 0 Null Null
3 2 1 02/20/2020 70
4 2 2 02/20/2020 60
5 3 0 Null Null
6 4 3 02/18/2020 56
These are my sample tables.
I want to show records from log table of zero as well as all assigned subject of user 1
Suppose user 1 has 2 subject 1 and 3.
Show records from logs where subjectid comes in 0 as well as 1,3
Required Output :
Logs
Id Userid SubjectId Examdate Percentage
1 1 1 02/20/2020 50
2 1 0 Null Null
3 2 1 02/20/2020 70
4 3 0 Null Null
5 4 3 02/18/2020 56
Query :
select * from logs where rdatetime >= '' and subjectid in (select id from subjectmaster where userid = 1)
'Or' did not work.It was giving wrong output.How to handle it.
If I understand correctly, you want a correlated subquery and condition like this:
select l.*
from logs l
where l.subjectid = 0 or
exists (select 1
from subjectmaster sm
where sm.userid = l.userid and
sm.subjectid = l.subjectid
);
You can do left join :
select l.*
from logs l left join
subjectmaster sm
on sm.userid = l.userid and
sm.subjectid = l.subjectid
where not (l.subjectid <> 0 and sm.subjectid is null);
This query will give you the desired result:
select *
from logs l
where subjectid = 0
OR
subjectid IN (select subjectid
from UserSubjectAssociation
where Userid = 1)
I need to create a new table base on two tables. I have a database in ms access and need to migrate.
tableT tableS
ID CustID DATE Exp1 Exp2 ID CustID DATE Tem1 Tem2
-------------------------------- ---------------------------------
1 1 1/1/00 5 5 1 1 1/1/00 3 4
2 2 1/1/00 1 3 2 2 1/1/00 5 0
3 1 3/1/00 3 2 3 1 5/1/00 0 3
4 3 4/1/00 4 1 4 3 6/1/00 0 0
Desired output table tableNew:
ID CustID DATE Exp1 Exp2 Tem1 Tem2
---------------------------------------------
1 1 1/1/00 5 5 3 4
2 2 1/1/00 1 3 5 0
3 1 3/1/00 3 2
4 3 4/1/00 4 1
5 1 5/1/00 0 3
6 3 6/1/00 0 0
If I use outer join, I will not get the output I need.
Any idea or help.
You want a full join. You can emulate this in MS Access using:
select t.CustID, t.DATE, t.Exp1, t.Exp2, s.tem1, s.tem2
from TableT as t left outer join
tableS as s
on t.CustId = s.CustId and t.date = s.date
union all
select s.CustID, s.DATE, null, null, s.tem1, s.tem2
from tableS as s left outer join
tableT as t
on t.CustId = s.CustId and t.date = s.date
where t.CustId is null;
I have 2 tables, staff_product and orders_with_over_20k_product.
staff_product
STAFF_ID PRODUCT_ID
---------- ----------
2 6
2 4
2 5
2 7
1 6
1 4
1 5
1 7
3 6
3 4
3 5
3 7
orders_with_over_20k_product
STAFF_ID PRODUCT_ID PQ
---------- ---------- ----------
1 4 20
2 5 100
1 5 10
1 7 8
2 7 1
2 4 10
2 6 100
1 6 100
3 4 1
I want to join them such that if there is a record in staff_product that has matching values in orders_with_over_20k_product then PQ will be copied, and if there isn't then PQ will be set to 0. I also want to preserve the order or product_id in staff_product (it's important for how my program handles this query). The desired output is as follows
STAFF_ID PRODUCT_ID PQ
---------- ---------- ---------
2 6 100
2 4 10
2 5 100
2 7 1
1 6 100
1 4 20
1 5 10
1 7 8
3 6 0
3 4 1
3 5 0
3 7 0
I'll be executing this select in a stored procedure and both the existing tables are currently views made of different queries. How would construct a query for my desired output?
I think you just want a left join and coalesce():
select sp.*, coalesce(ow.pq, 0) as pq
from staff_product sp left join
orders_with_over_20k_product ow
on sp.staff_id = ow.staff_id and sp.product_id = ow.product_id
You can do a left join and coalesce():
select
p.*,
coalesce(o.pq, 0) pq
from staff_product p
left join orders_with_over_20k_product o
on o.product_id = p.product_id and o.staff_id = p.staff_id
Please use below SQL code for this issue.
SELECT A.STAFF_ID
,A.PRODUCT_ID
,coalesce(B.PQ, 0) AS PQ
FROM staff_product AS A
LEFT JOIN orders_with_over_20k_product AS B ON A.STAFF_ID = B.STAFF_ID
AND A.PRODUCT_ID = B.PRODUCT_ID
I would like to apply a for loop in this sql statement in ms-access something like:
for(i=0;i<8;i++)
{
UPDATE current_stock SET current_stock.quantity = DLookup("quantity","current_stock","stock_id=i")-DLookup("req_quantity","Bom_dell","lap_id=(SELECT lap_id FROM laptop_info WHERE model_name='Dell Inspiron')" And "stock_id=i")
WHERE stock_id=1;
}
Please advise if there is any method in MS-access to be able to do something similar to a for loop using sql queries.
Bom_dell
bom_id lap_id stock_id req_quantity
1 1 1 1
2 1 2 3
3 1 3 6
4 1 4 1
5 1 5 1
6 1 6 2
7 2 7 7
8 2 8 8
9 2 9 1
10 2 10 1
11 2 11 1
12 2 12 3
current_stock
ID lap_id stock_id quantity
1 1 1 11
2 1 2 11
3 1 3 11
lap_info
lap_id model_name model_num price
1 Dell Inspiron INS81 35000
2 Dell XLS XL91 24000
Sample query
UPDATE (SELECT laptop_info.model_name, current_stock.stock_id, Bom_dell.req_quantity, current_stock.quantity
FROM (current_stock INNER JOIN laptop_info ON current_stock.lap_id = laptop_info.lap_id) INNER JOIN Bom_dell ON current_stock.stock_id = Bom_dell.stock_id)
SET quantity=quantity-req_quantity
WHERE stock_id BETWEEN 1 AND 3
AND model_name='Dell Inspiron'
UPDATE (SELECT laptop_info.model_name, current_stock.stock_id, Bom_dell.req_quantity, current_stock.quantity
FROM (current_stock INNER JOIN laptop_info ON current_stock.lap_id = laptop_info.lap_id) INNER JOIN Bom_dell ON current_stock.stock_id = Bom_dell.stock_id) SET quantity = quantity-req_quantity
WHERE stock_id BETWEEN 1 AND 3
AND model_name IN ([Forms]![Invoice1]![laptop_id])
You seem to be looking for something on the lines of:
UPDATE (current_stock
INNER JOIN laptop_info ON laptop_info.stock_id=current_stock.stock_id)
INNER JOIN Bom_dell ON Bom_dell.lap_id = laptop_info.lap_id
SET current_stock.quantity = current_stock.quantity - Bom_dell.req_quantity
WHERE stock_id Between 1 And 8
AND model_name='Dell Inspiron'
Try this. I have used aliases - a is for the current_stock table and b is for the sub query. This assumes that you have one line per stock id in bom_dell.
UPDATE current_stock AS a
INNER JOIN (
SELECT bom_dell.stock_id, lap_info.model_name, bom_dell.req_quantity
FROM bom_dell
INNER JOIN lap_info ON bom_dell.lap_id = lap_info.lap_id
WHERE (((bom_dell.stock_id) Between 1 And 3)
AND ((lap_info.model_name)="Dell Inspiron"))) AS b
ON a.Stock_id = b.Stock_id SET a.quantity = [a].[quantity]+[b].[req_quantity];