I have the following tables:
Table Main:
TestNumber PassageNumber QuestionNumber
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
Table Child:
TestNumber PassageNumber QuestionNumber User SelectedAnswer
1 1 1 X A
1 2 2 X B
I want to show the data in main table that is not in child table based on a test number and user. So the results i am looking for are the following where the rows from main table are the ones NOT in child:
TestNumber PassageNumber QuestionNumber
1 1 2
1 1 3
1 2 1
1 2 3
I have tried the following query and variations with no luck:
SELECT a.passagenumber, a.questionnumber FROM Main a left outer join
Child b on a.testnumber=b.testnumber where b.user = 'X'
and b.testnumber=1 and a.testnumber=1 and b.selectedanswer is not null
I understand if i had a unique id this would be easy to solve but in this case that is not an option. Any help would be much appreciated.
I thin you can use not in
SELECT a.passagenumber, a.questionnumber FROM Main a
where ( a.testnumber, a.passagenumber, a.questionumber)
not in ( select b.testnumber, b.passagenumber, b.questionumber
from Child b where b.user = 'X' )
Can you join the tables on the three fields, using left join and where the child table value is null?
SELECT p.TestNumber
,p.PassageNumber
,p.QuestionNumber
FROM Parent p
LEFT JOIN Child c ON c.TestNumber = p.TestNumber
AND c.PassageNumber = p.PassageNumber
AND c.QuestionNumber = p.QuestionNumber
AND c.[User] = 'X'
WHERE c.TestNumber IS NULL;
Related
I have these tables
One text has many-many items writer,line
ttext_obj table
test obj
1 text1
2 text2
3 text3
4 text4
text_obj_writers table
text writer
1 2
2 3
2 4
text_obj_line table
text line
1 2
4 3
1 4
So, I want to pick up the rows of text_obj which have at reast one writer or one line.
For now I made code like this .
The text_obj id which has at least one write
SELECT text.id FROM `text_obj` text
inner join text_obj_writers writer
on writer.obj_id = text.id group by text.id
//it returns
1
2
The text_obj id which have at least one line
SELECT text.id FROM `text_obj` text
inner join text_obj_lines line
on line.obj_id = text.id group by text.id
//it returns
1
4
But I want to take or of these
1
2
4
How can I concatenate two tables by or ?
Use exists:
select o.*
from text_obj o
where exists (select 1
from text_obj_writers tow
where tow.obj_id = o.id
) or
exists (select 1
from text_obj_lines tol
where tol.obj_id = o.id
) ;
This is much better than using aggregation, because you do not need to remove duplicates after joining the tables together.
You could use exists:
select o.*
from ttext_obj o
where
exists (select 1 from text_obj_writers writer w where w.obj_id = o.id)
or exists (select 1 from text_obj_lines l where l.obj_id = o.id)
You can do it with UNION which will also remove duplicates:
select obj_id id from test_obj_writers
union
select obj_id id from test_obj_line
I assume that all obj_ids of both tables exist in the table text_obj.
I am having trouble with my MySQL query. I want to show the id FROM one table using left join 3 another table.
What do I want is :
Show id IS NULL in 1 of another table
And having COUNT() < (get column in another table)
I tried this but it is still wrong:
SELECT p.id FROM penerimaan AS p
LEFT JOIN perangkat AS per ON per.id_penerimaan=p.id
LEFT JOIN permintaan AS pa ON pa.id=p.id_permintaan
LEFT JOIN konfirmasi_permintaan AS k ON k.id_permintaan=pa.id
WHERE per.id_penerimaan IS NULL
GROUP BY p.id
HAVING COUNT(per.id_penerimaan) < k.jumlahConfirm //how to get column in another table
ORDER BY p.id ASC
the table I have
table permintaan
id jumlah status
2 3 Confirmed
3 5 Confirmed
-----------------------------------------------
table penerimaan
id id_permintaan date
1 2 2017-07-12
2 3 2017-08-12
-----------------------------------------------
table konfirmasi_permintaan
id id_permintaan jumlahConfirmed
1 2 3
2 3 3
-----------------------------------------------
table perangkat
id id_penerimaan serial type
1 1 766544 SG90D-08-AS
2 1 552411 SLM2008T-EU
3 1 552411 SLM2008T-TU
4 2 561434 SG95-24-AS
I desired result like this
id_penerimaan
2
though id_penerimaan in table perangkat IS NULL but still show, because count(perangkat.id_penerimaan) is 2 in table perangkat less than jumlahConfirm in table konfirmasi_permintaan
Thank you
Removing WHERE per.id_penerimaan seems to solve the problem. You also have to add k.jumlahConfirmed to the SELECT list, because HAVING can only access values in the select list, not columns from the original tables.
SELECT p.id, k.jumlahConfirmed FROM penerimaan AS p
LEFT JOIN perangkat AS per ON per.id_penerimaan=p.id
LEFT JOIN permintaan AS pa ON pa.id=p.id_permintaan
LEFT JOIN konfirmasi_permintaan AS k ON k.id_permintaan=pa.id
GROUP BY p.id
HAVING COUNT(per.id_penerimaan) < k.jumlahConfirmed
DEMO
I have 3 tables in this format:
Table Child:
id|parent_id|grandparent_id
1 1 null
2 2 null
3 3 null
Table Parent:
id|grandparent_id
1 1
2 1
3 2
Table GrandParent:
id
1
2
I need to run a query that updates grandparent_id column in Child table based on the grandparent_id in Parent table. So the correct final form of Child table will be:
Table Child:
id|parent_id|grandparent_id
1 1 1
2 2 1
3 3 2
This is the query I have at the moment but it returns more than 1 row which is wrong:
update child set grandparent_id = (
select gpd.id from GrandParent gp, Parent p
where p.grandparent_id = gp.id)
where 1
You can use the following query to get the UPDATE:
UPDATE Child SET Child.grandparent_id = (
SELECT GrandParent.id
FROM GrandParent INNER JOIN Parent ON GrandParent.id = Parent.grandparent_id
WHERE Parent.id = parent_id
) WHERE Child.grandparent_id IS NULL;
Demo: http://sqlfiddle.com/#!9/894e97/1/0 (modified table content to show the UPDATE is working).
Hint: Your "correct" example is wrong: GrandParent of Parent with id = 2 is 1!
Please give a try on the below query:
Update child c,parent p
set c.grandparent_id = p.grandparent_id
where c.id = parent.id
and c.grandparent_id = ' '
I have a statement like so:
select * from category a
inner join category b on a.row=b.relatedRow
inner join category c on b.row=c.relatedRow where a.row=?
I would like to get the number of "levels" like so:
If a has rows, level=1, If b has rows, level=2, If c has rows, level=3.
How can I do this?
Example
row, relatedRow
1,null
2,1
3,2
4,3
5,2
6,5
So, 1 is not related to any row, 2 is related to 1, 3 is related to 2 and so on...
If row=1, level 1 exists since 1 exists
level 2 exists since 2 is related to 1
level 3 exists since 3 and 5 is related to 2
level 4 exists since 6 is related to 5 and 4 is related to 3
Therefore the this tree goes down 4 levels.
try with something along the lines:
select
sum(case when not b.relatedRow is null then 1 else 0 end) as level1_total
sum(case when not c.relatedRow is null then 1 else 0 end) as level2_total
from category a
left join category b on a.row=b.relatedRow
left join category c on b.row=c.relatedRow where a.row=?
of course, you can modify the conditions in the case to suit your definition of has rows
select
max(
case
when c.relatedRow is not null then 3
when b.relatedRow is not null then 2
else 1
end
) as "levels"
from
A a
left outer join B b on b.relatedRow = a.row
left outer join C on c.relatedRow = b.row
Now seeing the edit to the question, I hope you see this pattern can be extended to a 4th level and beyond. If you add a where clause to do any filtering make sure that you only add conditions against A or you'll mess up the outer joins.
These are the two tables Fruit and Fruit_types.There is a m:n relationship between the two tables so we have the third table fruit_type_fruit which has the primary key from the above two tables. The tables look like this
Fruit
ID NAME
1 A
2 B
3 C
Fruit_type
ID LABEL
1 CITRIC
2 DRUPES
3 UNCATALOGUED
Fruit_type_Fruit
Fruit_id Fruit_type
1 1
1 2
1 3
2 1
3 3
Problem Statement: Some fruits even though they have a category(i.e label) get label as Uncatalogued.
For ex:-
A gets the following labels : Citric, drupes and uncatalogued.
B has citric ,
C has Uncatalogued.
Now I need a query to delete all the records which have a suitable label but still have uncatalogued label too.
In the above example
A record which is uncatalogued should be deleted and not
A Citric and Drupes neither
C Uncatalogued.
How about something like this
SQL Fiddle DEMO
DELETE ftf
FROM fruit_type_fruit ftf
WHERE Fruit_type_ID = 3
AND Fruit_ID IN
(
SELECT *
FROM (
SELECT DISTINCT Fruit_ID
FROM fruit_type_fruit f
WHERE f.Fruit_type_ID = 3
) ss
WHERE Fruit_ID IN (
SELECT *
FROM (
SELECT DISTINCT Fruit_ID
FROM fruit_type_fruit f
WHERE f.Fruit_type_ID <> 3
) s)
)