I'm fairly new to sql. This might be basic. I have two tables one with groups and one with members, I want to link them up so that a third table contains id_group and id_member. The value MYGROUP is supplied during the import. I tried this:
insert ignore into member_group (id_group, id_member)
values ( ( select id_group from group where group_name='MYGROUP' ) ,
( select id_member from member ) );
But I end up with one row in member_group containing a null value.
on it's own this yields 1 for example:
select id_group from group where group_name='MYGROUP';
+----------+
| id_group |
+----------+
| 1 |
+----------+
on it's own this yields a list of id_members
mysql> select id_member from member;
+-----------+
| id_member |
+-----------+
| 123 |
| 456 |
| 789 |
I want member_group to then look like this
+-----------+----------+
| id_group |id_member |
+-----------+----------+
| 1 | 123 |
| 1 | 456 |
| 1 | 789 |
How can I do this (without resorting to shell scripts, for loops and sed) ?
As requested,
mysql> select * from group;
+----------+------------------+
| id_group | group_name |
+----------+------------------+
| 1 | vip-member |
| 2 | standard-member |
mysql> select * from member;
+-----------+----------+
| id_member | fullname |
+-----------+----------+
| 123 | Bob |
| 456 | Pete |
Which, if I could get it working, should look like below.
mysql> select * from member_group;
+------------------+----------+-----------+
| id_member_groups | id_group | id_member |
+------------------+----------+-----------+
| 1 | 1 | 123 |
| 2 | 1 | 456 |
| 3 | 1 | 789 |
| 4 | 2 | 123 |
| 5 | 2 | 789 |
id_group is supplied during the import phase. One batch of say 200 members, will be members of the same id_group. I was thinking about adding the group_id to a temporary table. But I'm a tad lost to be honest.
You can do a cross join to achieve your goal.
insert ignore into member_group (id_group, id_member)
select member_group.id_group, member.id_member
from member_group
cross join member
where group_name = 'MYGROUP';
Related
I have a table like this with 8 rows
+----+------+------+--------+
| id | type | attr1 | attr2 |
+----+------+-------+-------+
| 1 | a | abcd | qwer |
| 2 | a | efgh | tyui |
| 2 | b | ijkl | opas |
| 3 | a | mnop | dfgh |
| 4 | a | qrst | jklz |
| 5 | a | uvwx | xcvb |
| 5 | b | yzab | nmqw |
| 6 | b | cdef | erty |
+----+------+-------+-------+
It is known than type can be either 'a' or 'b'.
I need to select the rows in such a way that if there are more than one rows with same id, then select the one with type 'a'. Else select the row with whatever type is present.
So my desired result should be like
+----+------+------+--------+
| id | type | attr1 | attr2 |
+----+------+-------+-------+
| 1 | a | abcd | qwer |
| 2 | a | efgh | tyui |
| 3 | a | mnop | dfgh |
| 4 | a | qrst | jklz |
| 5 | a | uvwx | xcvb |
| 6 | b | cdef | erty |
+----+------+-------+-------+
I have a MySQL query
SELECT t.id,
CASE
WHEN count(t.id) > 1 THEN 'a'
ELSE t.type
END `type`
FROM table1 t
GROUP BY t.id
ORDER BY t.type ASC
which gives this result
+----+------+
| id | type |
+----+------+
| 1 | a |
| 2 | a |
| 3 | a |
| 4 | a |
| 5 | a |
| 6 | b |
+----+------+
But I need the respective row with all columns.
How to do that?
Note that the MySQL version that I have is 5.7.12.
You don't mention if multiple a's with the same id are possible or what to do in that case. I'm going to assume you want all a rows included. To do that, you just need to exclude b rows when there is a corresponding a row:
select t.*
from table1 t
left join table1 t2 on t2.id=t.id and t.type='b' and t2.type='a'
where t2.id is null;
you also can do it using window function:
select * from
(
select * , row_number() over (partition by id order by case when type = 'a' then 0 else 1 end) rn
) t
where rn = 1;
Hmmm . . . I would be inclined to use not exists:
select t.*
from t
where t.type = 'a' or
not exists (select 1
from t t2
where t2.id = t.id and t2.type = 'a'
);
I have a Table "Teaches". This has a PK and a Name.
mysql> Select * from Teacher;
+-----+---------+
| TID | Tname |
+-----+---------+
| 1 | RC |
| 2 | Dinesha |
| 3 | JLT |
+-----+---------+
I have another Table "TeachesSubject". It has _surrid which is a PK, the TID references Teacher and SName is the Name of the subject taught.
mysql> select * from TeachesSubject;
+---------+------+-------+
| _surrid | TID | SNAME |
+---------+------+-------+
| 100 | 1 | DBMS |
| 101 | 1 | DM |
| 102 | 2 | DBMS |
| 103 | 2 | OOAD |
| 104 | 3 | OOAD |
| 105 | 3 | SE |
+---------+------+-------+
These two tables are already populated. I now run a query in TeachesSubject that points out the SNAMEs with duplicate values.
mysql> select SNAME from TeachesSubject group by SNAME having count(*)>1;
+-------+
| SNAME |
+-------+
| DBMS |
| OOAD |
+-------+
Once I detect this, I want my sql script to create a new table:
Teaches
_surrId TID
100 1
101 1
100 2
103 2
103 3
105 3
My old Teaches Subject Must look like
mysql> select * from TeachesSubject;
+---------+------+
| _surrid | SNAME |
+---------+-------+
| 100 | DBMS |
| 101 | DM |
| 103 | OOAD |
| 105 | SE |
+---------+------+
How Do I do this?
Here's how you can do it:
CREATE TABLE TeachesSubject2
(`_surrid` int, `SNAME` varchar(4))
;
INSERT INTO TeachesSubject2
SELECT MIN(_surrid), sname
FROM TeachesSubject
GROUP BY sname
;
CREATE TABLE Teaches
(`_surrid` int, `TID` int)
;
INSERT INTO Teaches
SELECT t2._surrid, t1.tid
FROM TeachesSubject AS t1
LEFT OUTER JOIN TeachesSubject2 AS t2
ON t1.sname = t2.sname
;
Working example is here: http://sqlfiddle.com/#!9/13d417/2
In future it would help if you created a fiddle yourself and attempted to write the SQL yourself. Then I wouldn't have to spend my time setting up for the answer, I could just fix whatever problem you are having.
So in order to know how many people in a table are called Johnny I would need to excecute the following query.
Query:
Select count(*) from mytable where first = 'Johnny';
It would give me 2 as the result.
What I wish to do however is record this number in the count column so that the end result comes out like this.
+--------+----------+
| First | COUNT |
+--------+----------+
| Johnny | 2 |
| Diane | 1 |
| Johnny | 2 |
| Harold | 1 |
| Amy | 3 |
| Roy | 2 |
| Amy | 3 |
| Amy | 3 |
| Roy | 2 |
+--------+----------+
Is there any query or procedure capable of resulting in this type of output?
To get your exact output, you need to use a subquery:
select
mytable.First,
counts.`COUNT`
from
mytable
join (
select
First,
count(*) `COUNT`
from
mytable
group by
First
) counts on mytable.First = counts.First;
Try this:
SELECT T1.First, T2.COUNT
FROM mytable T1 JOIN
(SELECT First, COUNT(*) as COUNT
FROM mytable
GROUP BY First) as T2 ON T1.First=T2.First
The result will be:
+--------+----------+
| First | COUNT |
+--------+----------+
| Johnny | 2 |
| Diane | 1 |
| Johnny | 2 |
| Harold | 1 |
| Amy | 3 |
| Roy | 2 |
| Amy | 3 |
| Amy | 3 |
| Roy | 2 |
+--------+----------+
I have a two tables :
mysql> select * from quizquestionbank;
| ID | QuestionFilePath | CorrectAnswer |
| 1 | p.wav | 1 |
| 2 | q.wav | 2 |
| 3 | a.wav | 3 |
| 4 | b.wav | 1 |
| 5 | m.wav | 3 |
Second table is :
mysql> select * from quizuserdetails;
| ID | MSISDN | QuestionIdDetails | AnswerRecord |
| 1 | 235346 | 1,3,4,5 | S,F,S,F |
| 2 | 564574 | 4,5,67,88 | F,S,F,s |
| 3 | 500574 | 5,55,66,44,2 | F,F,F,F |
I want to get the IDs from table 1 which are not there in QuestionIdDetails column of second table.
I tried query
Select ID from quizquestionbank where ID not in (Select QuestionIdDetails from quizuserdetails where msisdn = '235346 ');
But this does not work
CAn anybody suggest a way to do it
Use find_in_set() to match the id to the list, but that's not all:
Select disting qb.ID
from quizquestionbank qb
left join quizuserdetails qd
on find_in_set(qb.id, QuestionIdDetails) > 0
and msisdn = '235346'
where qd.id is null
There's 3 key things going on here:
using a left join and including the extra condition in the join condition
the use of find_in_set(), which finds a value in a CSV string, to make the join
using a where clause that filters out matches, leaving only the missed joins
Lets say I have a table with the following rows/values:
+--------+----------+
| ID | adspot |
+--------+----------+
| 1 | A |
| 2 | B |
| 3 | A |
| 4 | B |
| 5 | C |
| 6 | A |
+--------+----------+
I need a way to select the values in adspot but only once if they're duplicated. So from this example I'd want to select A once and B once. The SQL result should look like this then:
+----------+
| adspot |
+----------+
| A |
| B |
| C |
+----------+
I'm using mySQL and PHP, in case anyone asks.
Thanks.
SELECT DISTINCT adspot FROM your_table; ( this may not perform well at all in large tables )
SELECT adspot FROM table GROUP BY adspot
see: http://www.tizag.com/mysqlTutorial/mysqlgroupby.php