mysql tuple comparison not exist - mysql

i have a question concerning the comparison of tuples in mysql.
I have two tables:
Person_ID | Class_ID | STATE
1 | 1 | 1
1 | 3 | 0
Person_ID | Class_ID
1 | 1
1 | 2
1 | 3
Thus, the second row is not existing in the first table. However, I want to combine the tables like:
Person_ID | Class_ID | STATE
1 | 1 | 1
1 | 2 | -1
1 | 3 | 0
Someone an idea, how I can do that?
I tried to play with exist, if, where, etc. :-(.

You can use a LEFT JOIN with COALESCE:
SELECT t2.Person_ID, t2.Class_ID,
COALESCE(t1.STATE,-1) AS STATE
FROM Table2 AS t2
LEFT JOIN Table1 AS t1
ON t2.Person_ID = t1.Person_ID AND t2.Class_ID = t1.Class_ID

Related

MySQL query to select group of IDs from one table, depending on query on a second table

I am sure this would be easy to google if I knew the right words to use, but I've tried and not come up with anything: apologies if this is a common question on SO.
I have one table which lists a set of records which can be one of 4 types.
table_1:
+-------+------------+------+
| id | value | type |
+-------+------------+------+
| 1 | x | 1 |
| 2 | y | 1 |
| 3 | z | 2 |
| 4 | a | 3 |
+-------+------------+------+
I have another table which references the id of this table and stores data
table_2:
+-------+------------+------+
| id | table_1_id |value |
+-------+------------+------+
| 1 | 4 | A |
| 2 | 2 | B |
| 3 | 3 | C |
| 4 | 2 | D |
+-------+------------+------+
I want to write a query that effects:
"Find all the records from table 1 which are of type 1, take the id's of those records, and find all the records in table 2 where 'table_1_id' which match one of that set of ids."
In the above very oversimplified table example that would result in the query returning records with ids 2 and 4 in table 2
Sounds like your looking for IN:
select *
from table2
where table_1_id in (select id from table1 where type = 1)
Or perhaps you could JOIN the tables:
select t2.*
from table2 t2
join table1 t1 on t2.table_1_id = t1.id
where t1.type = 1
Joining the tables could result in duplicate records. Depends on your needs.
SELECT t1.value,t1.type,t2.value FROM table1 t1,table2 t2 WHERE t1.id = t2.table_1_id AND t1.type = 1;

Count rows with specific value over multiple rows

Its very hard for to set a proper title, because I dont know how I describe my problem.
I have a table like this:
dlID | dl_seID | dlEpisode | dlFlag
___________________________________
1 | 1 | 1 | 0
2 | 1 | 2 | 1
3 | 1 | 3 | 1
4 | 2 | 1 | 1
5 | 2 | 2 | 0
6 | 3 | 1 | 0
What i want is a select query where I get something like this:
dlID | dl_seID | dlEpisode | dlFlag | dlFlagCount
_________________________________________________
1 | 1 | 1 | 0 | 2
2 | 1 | 2 | 1 | 2
3 | 1 | 3 | 1 | 2
4 | 2 | 1 | 1 | 1
5 | 2 | 2 | 0 | 1
6 | 3 | 1 | 0 | 0
dlFlagCount shoud be a counter of dlFlag = 1 where dl_seID = dl_seID.
Second try:
I need a value where I see how many Flags have the value 1 with the same dl_seID.
Is that possible?
I hope you guys know what I want^^
Regards
Try this:
select
a.*,
ifnull(b.ctflags,0)
from
tablea a left join
( select dl_seID, count(dlFlag) ctflags
from tablea
where dlFlag=1
group by dl_seID ) b on (a.dl_seID = b.dl_seID)
The left join is just to get the registry with 0 flags
See the fiddle: http://sqlfiddle.com/#!2/ef9b0/5
EDIT:
As op requested some explanation, here it goes:
What you asked is to count the amount of flags by the dl_seID and to do that you need to do this you separeta your problems, first you get the count for the dl_seID by flags, this is this subquery:
select dl_seID, count(dlFlag) ctflags
from tablea
where dlFlag=1
group by dl_seID
This became a 'separe table' or a new group of data, whatever you wanna call it. Then you have to join this with your original data (from your table) like the query for answer.
The left join part is because maybe there are some data that wont complain with where dlFlag=1 therefore if you want to get then as 0 you have to bring all values from table that exists or not on our created subgroup. And this ifnull(b.ctflags,0) is for theese data data exists on your table but has no flags (for your problem). If you use just b.ctflags it will bring null.
SELECT x.*
, COALESCE(y.flagcount,0) flagcount
FROM my_table x
LEFT
JOIN
( SELECT seID
, COUNT(*) flagcount
FROM my_table
WHERE flag = 1
GROUP
BY seid
) y
ON y.seid = x.seid;

how to write this self join based on three columns

Hello there I have a following table
------------------------------------------
| id | language | parentid | no_daughter |
------------------------------------------
| 1 | 1 | 0 | 2 |
------------------------------------------
| 1 | 1 | 0 | 2 |
------------------------------------------
| 2 | 1 | 1 | 1 |
------------------------------------------
| 2 | 2 | 1 | 1 |
------------------------------------------
| 3 | 1 | 1 | 0 |
------------------------------------------
| 3 | 2 | 1 | 0 |
------------------------------------------
| 4 | 1 | 2 | 0 |
------------------------------------------
| 4 | 2 | 2 | 0 |
------------------------------------------
| 5 | 1 | 2 | 0 |
------------------------------------------
| 5 | 2 | 2 | 1 |
-----------------------------------------
| 5 | 1 | 4 | 1 |
------------------------------------------
| 5 | 2 | 4 | 1 |
------------------------------------------
Scenario
Every record has more than one rows in table with different language ids. parentid tells who is the parent of this record. no_daughter columns tells against each record that how many child one record has. Means in Ideal scenario If no_daughter has value 2 of id = 1 , it means 1 should be parentid of 2 records in same table. But If a record has more than one exitance with respect to language, it will be considered as one record.
My Problem
I need to find out those records where no_daughter value is not correct. It means if no_daughter is 2, there must be two records whoes parentid has that id. In above case record with id = 1 is valid. But record having id = 2 is not valid because the no_daughter = 1 but actual daughter of this record is 2. Same is the case with id=4
Can any body tell me how can I find these faulty records?
Updated after answers
Ken Clark has and shola has given answer which return same result for example shola query is
SELECT DISTINCT
id
FROM
tbl_info t
INNER JOIN
(SELECT
parentid,
COUNT(DISTINCT id) AS childs
FROM
tbl_info
GROUP BY parentid) AS parentchildrelation
ON t.id = parentchildrelation.parentid
AND t.no_daughters != parentchildrelation.childs
This query is returning those ids who have been used as parentid somewhere in table but having wrong no_daughter values. But not returning ids that has value in no_daugter columns but have not been used as parentid any where in table. For exampl id = 5 has no_daughter = 1 but it is not used as parentid in table. So it is also a faulty record. But above query is not capturing such records.
Any help will be much appreciated.
Try this:
SELECT DISTINCT
id
FROM
tbl_info t
Left JOIN
(SELECT
parentid,
COUNT(DISTINCT id) AS childs
FROM
tbl_info
GROUP BY parentid) AS parentchildrelation
ON t.id = parentchildrelation.parentid
Where t.no_daughters != parentchildrelation.childs
Try this:
SELECT id FROM tinfo t inner join
(SELECT parentid, COUNT(distinct language ) as childs FROM tinfo group by parentid) as summary
on t.id=summary.parentid and t.no_daughters!= summary.childs
try this
Select Distinct * From tablename t
Left Join
(
Select COUNT(t1.Id) Doughter,t1.parentid,t1.language From tablename t1 Group By t1.parentid,t1.language
)tbl
On t.id=tbl.parentid And tbl.language=t.language And t.no_daughter<>tbl.Doughter

how is "USING" and "ON" keywords are useful in this code

SELECT table1.PrimaryKey(Some ID), table2.nameOfSomething
FROM table1
INNER JOIN table2
Here is the part i don't get :
USING(id)
this ID is table1 foreign key, and table2 primary key
i dont really get it..
table1.ID values:
25 Rows:
row 1-5 = 1 , row 6-10 = 2 , row 11-15 = 3 , row 16-20 = 4 , row 21-25 = 5
table2.ID values :
5 Rows:
row 1 = 1 , row 2 = 2 , row 3 = 3 , row 4 = 4 , row 5 = 5
i test it and i get different result without it, how comes?
Note : Table1 contains interests, Table2 contains categories for these interests
feel free to ask for more information
USING specifies that a join should be performed by joining on the listed columns in both tables. That is
SELECT t1.col1,
t1.col2,
t2.col1
FROM table1 AS t1
INNER JOIN table2 AS t2
USING (col1)
is the same as
SELECT t1.col1,
t1.col2,
t2.col1
FROM table1 AS t1
INNER JOIN table2 AS t2
ON t1.col1 = t2.col1
For reference, see the MySql homepage.
USING is a equi-join and relies on attribute names for the same data element remaining the same between tables.
ON is more flexible: because it requires you to explicitly specify the attribute name in both tables, attribute names for the same data element can be the same or they can be different between the tables. Also, it is a theta-join, meaning that the join type can be any condition, including equality. As a result of this flexibility, ON is more verbose.
| Table1: | Table2: |
| id | id | table1_id |
| 1 | 1 3 |
| 2 | 2 2 |
| 3 | 3 1 |
If you join the above two tables together with USING(id) it will match rows where the id value in Table1 are the same as the id value in Table2...
SELECT * FROM table1 JOIN table2 USING(id)
| id | id table1_id |
| 1 | 1 3 |
| 2 | 2 2 |
| 3 | 3 1 |
But, the id in Table2 might have nothing to do with the id in Table1. If that's the case, you can use ON to be specific about how you match records together...
SELECT * FROM table1 JOIN table2 ON table1.id = table2.table1_id
| id | id table1_id |
| 1 | 3 1 |
| 2 | 2 2 |
| 3 | 1 3 |
If you specify nothing at all, you match every record in one table, against every record in the other table...
SELECT * FROM table1 CROSS JOIN table2
| id | id table1_id |
| 1 | 1 3 |
| 1 | 2 2 |
| 1 | 3 1 |
| 2 | 1 3 |
| 2 | 2 2 |
| 2 | 3 1 |
| 3 | 1 3 |
| 3 | 2 2 |
| 3 | 3 1 |

mysql select ordernumber by group

I'm trying to do something like 'select groupwise maximum', but I'm looking for groupwise order number.
so with a table like this
briefs
----------
id_brief | id_case | date
1 | 1 | 06/07/2010
2 | 1 | 04/07/2010
3 | 1 | 03/07/2010
4 | 2 | 18/05/2010
5 | 2 | 17/05/2010
6 | 2 | 19/05/2010
I want a result like this
breifs result
----------
id_brief | id_case | dateOrder
1 | 1 | 3
2 | 1 | 2
3 | 1 | 1
4 | 2 | 2
5 | 2 | 1
6 | 2 | 3
I think I want to do something like described here MySQL - Get row number on select, but I don't know how I would reset the variable for each id_case.
This will give you how many records are there with this id_case value and a date less than or equal to this date value.
SELECT t1.id_brief,
t1.id_case,
COUNT(t2.*) AS dateOrder
FROM yourtable AS t1
LEFT JOIN yourtable AS t2 ON t2.id_case = t1.id_case AND t2.date <= t1.date
GROUP BY t1.id_brief
Mysql is permissive about columns which can be queries using GROUP BY. With a more stric DBMS you may need GROUP BY t1.id_brief, t1.id_case.
I strongly advise you to have the right indexes on the table:
CREATE INDEX filter1 ON yourtabl (id_case, date)