I have 2 tables.
1.
**code**
id
name
2.
**code_category**
id
code_id
category_id
discount
I have a list of 15000 codes in the database without the code_category yet. I only have 1 sample one to reference in code_category. I have to mass add in the code_category with 20 categories per code.
I am thinking of left joining both tables to get where code_id is null that gets me all the un-attached codes but I need another select statement to get the 20 different types of code_category rows to enter per code.
insert into code_category (code_id, category_id, discount)
values
(select id from code c
left join code_category cc on cc.code_id = c.id
where cc.code_id is null)
union
(select categoryid, discount from code_category where c.id = 123)
123 being the reference id.
I built a simplified example of your tables in a SQL Fiddle, then ran just the select (shown below) to see what rows would be inserted. See if this example answers your question.
Note how in the select I left join twice, once to get a list of categories, and again to find the missing ones.
SQL Fiddle
MySQL 5.6 Schema Setup:
CREATE TABLE IF NOT EXISTS `code` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
ENGINE=MyISAM
AUTO_INCREMENT=1
DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci
COMMENT '';
CREATE TABLE IF NOT EXISTS `code_category` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`codeid` INT(11) UNSIGNED NULL DEFAULT NULL,
`categoryid` INT(11) UNSIGNED NULL DEFAULT NULL,
`discount` INT(11) UNSIGNED NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_codecategory_catid` (`categoryid`),
KEY `idx_codecategory_codeid` (`codeid`)
)
ENGINE=MyISAM
AUTO_INCREMENT=1
DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci
COMMENT '';
INSERT INTO `code`
(`id`,`name`)
VALUES
(1,'code1'),
(2,'code2'),
(3,'code3'),
(4,'code4');
INSERT INTO `code_category`
(`codeid`,`categoryid`,`discount`)
VALUES
(1,1,3),
(2,1,2),
(1,2,2),
(1,3,3),
(1,4,2),
(1,5,2),
(1,6,2),
(1,7,2),
(1,8,2),
(1,9,2),
(1,10,2),
(1,11,2),
(1,12,2),
(1,13,2),
(1,14,2),
(1,15,2),
(1,16,2),
(1,17,2),
(1,18,2),
(1,19,2),
(1,20,2);
Query 1:
SELECT
c.id,
cc1.codeid,
cc1.categoryid,
cc1.discount
FROM code c
LEFT JOIN code_category cc1
ON cc1.codeid = 1
LEFT JOIN code_category cc
ON cc.codeid = c.id AND cc.codeid = cc1.codeid
WHERE cc.codeid is null
ORDER BY c.id,cc1.codeid,cc1.categoryid
Results:
| id | codeid | categoryid | discount |
|----|--------|------------|----------|
| 2 | 1 | 1 | 3 |
| 2 | 1 | 2 | 2 |
| 2 | 1 | 3 | 3 |
| 2 | 1 | 4 | 2 |
| 2 | 1 | 5 | 2 |
| 2 | 1 | 6 | 2 |
| 2 | 1 | 7 | 2 |
| 2 | 1 | 8 | 2 |
| 2 | 1 | 9 | 2 |
| 2 | 1 | 10 | 2 |
| 2 | 1 | 11 | 2 |
| 2 | 1 | 12 | 2 |
| 2 | 1 | 13 | 2 |
| 2 | 1 | 14 | 2 |
| 2 | 1 | 15 | 2 |
| 2 | 1 | 16 | 2 |
| 2 | 1 | 17 | 2 |
| 2 | 1 | 18 | 2 |
| 2 | 1 | 19 | 2 |
| 2 | 1 | 20 | 2 |
| 3 | 1 | 1 | 3 |
| 3 | 1 | 2 | 2 |
| 3 | 1 | 3 | 3 |
| 3 | 1 | 4 | 2 |
| 3 | 1 | 5 | 2 |
| 3 | 1 | 6 | 2 |
| 3 | 1 | 7 | 2 |
| 3 | 1 | 8 | 2 |
| 3 | 1 | 9 | 2 |
| 3 | 1 | 10 | 2 |
| 3 | 1 | 11 | 2 |
| 3 | 1 | 12 | 2 |
| 3 | 1 | 13 | 2 |
| 3 | 1 | 14 | 2 |
| 3 | 1 | 15 | 2 |
| 3 | 1 | 16 | 2 |
| 3 | 1 | 17 | 2 |
| 3 | 1 | 18 | 2 |
| 3 | 1 | 19 | 2 |
| 3 | 1 | 20 | 2 |
| 4 | 1 | 1 | 3 |
| 4 | 1 | 2 | 2 |
| 4 | 1 | 3 | 3 |
| 4 | 1 | 4 | 2 |
| 4 | 1 | 5 | 2 |
| 4 | 1 | 6 | 2 |
| 4 | 1 | 7 | 2 |
| 4 | 1 | 8 | 2 |
| 4 | 1 | 9 | 2 |
| 4 | 1 | 10 | 2 |
| 4 | 1 | 11 | 2 |
| 4 | 1 | 12 | 2 |
| 4 | 1 | 13 | 2 |
| 4 | 1 | 14 | 2 |
| 4 | 1 | 15 | 2 |
| 4 | 1 | 16 | 2 |
| 4 | 1 | 17 | 2 |
| 4 | 1 | 18 | 2 |
| 4 | 1 | 19 | 2 |
| 4 | 1 | 20 | 2 |
|----|--------|------------|----------|
You may need to change the column names to match your tables.
Related
We have a Mysql table user_documents. This table maps document with a user.
Data Definition of the table
id - primary key of the table
document_id - foreign key to the document table
user_id - foreign key to the user table.
hierarchy_order - order of hierarchy.
Sample table data
| id | document_id | user_id | hierarchy_order |
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
| 3 | 1 | 3 | 3 |
| 4 | 1 | 4 | 4 |
| 5 | 2 | 1 | 1 |
| 6 | 2 | 3 | 2 |
| 7 | 2 | 2 | 3 |
| 8 | 2 | 4 | 4 |
| 9 | 3 | 2 | 1 |
| 10 | 3 | 1 | 2 |
| 11 | 3 | 3 | 3 |
| 12 | 3 | 4 | 4 |
| 13 | 4 | 1 | 1 |
| 14 | 4 | 3 | 2 |
| 15 | 4 | 4 | 3 |
| 16 | 4 | 2 | 4 |
We have a hierarchy table list the user in a simple hierarchy. This table is changed frequently and order of users gets changed.
We cannot rely on the hierarchy table as it changes frequently. Hence we are logging the document_id with user_id and what hierarchy order that user was.
For the document_id = 1 in the user_documents table, the hierarchy was.
level 1 (top level) - user_id - 1
level 2 - user_id - 2
level 3 - user_id - 3
level 4 - user_id - 4
Problem Statement
We want to select all records/rows for user_id 2 and other users where their hierarchy order is greater than or equal to user_id 2 hierarchy_order for all document_id.
Expected output
| id | document_id | user_id | hierarchy_order |
| 2 | 1 | 2 | 2 |
| 3 | 1 | 3 | 3 |
| 4 | 1 | 4 | 4 |
| 7 | 2 | 2 | 3 |
| 8 | 2 | 4 | 4 |
| 9 | 3 | 2 | 1 |
| 10 | 3 | 1 | 2 |
| 11 | 3 | 3 | 3 |
| 12 | 3 | 4 | 4 |
| 16 | 4 | 2 | 4 |
We are using MySQL Database and not sure how to achieve this.
My tables structure:
// posts
+----+----------------------------------------+-----------+
| Id | body | user_id |
+----+----------------------------------------+-----------+
| 1 | content1 | 2 |
| 2 | content2 | 9 |
| 3 | content3 | 6 |
| 4 | content4 | 4 |
| 5 | content5 | 2 |
| 6 | content6 | 8 |
| 7 | content7 | 4 |
| 8 | content8 | 2 |
+----+----------------------------------------+-----------+
// votes
+----+---------+-------+
| id | post_id | value |
+----+---------+-------+
| 1 | 2 | 1 |
| 2 | 3 | -1 |
| 3 | 2 | 1 |
| 4 | 8 | -1 |
| 5 | 1 | 1 |
| 6 | 8 | 1 |
| 7 | 2 | -1 |
| 8 | 8 | -1 |
| 9 | 2 | 1 |
+----+---------+-------+
I need to select posts that have more than 1 vote total score. So this is expected output:
+----+----------------------------------------+-----------+-------------+
| Id | body | user_id | total_votes |
+----+----------------------------------------+-----------+-------------+
| 2 | content2 | 9 | 2 |
+----+----------------------------------------+-----------+-------------+
How can I do that?
create table qanda
( id int not null,
body varchar(100) not null,
user_id int not null
);
insert qanda values
(1,'a',2),
(2,'a',9),
(3,'a',6),
(4,'a',4),
(5,'a',2),
(6,'a',8),
(7,'a',2),
(8,'a',2);
create table votes
( id int not null,
post_id int not null,
value int not null
);
insert votes values
(1,2,1),
(2,3,-1),
(3,2,1),
(4,8,-1),
(5,1,1),
(6,8,1),
(7,2,-1),
(8,8,-1),
(9,2,1);
Query
select q.id,q.body,q.user_id,sum(v.value) as votes
from qanda q
join votes v
on v.post_id=q.id
group by q.id,q.body,q.user_id
having votes>1;
+----+------+---------+-------+
| id | body | user_id | votes |
+----+------+---------+-------+
| 2 | a | 9 | 2 |
+----+------+---------+-------+
I have this table, its name is puntajes:
+---------------+---------------+---------+
| estudiante_ID | evaluacion_ID | puntaje |
+---------------+---------------+---------+
| 1 | 1 | 15 |
| 2 | 1 | 11 |
| 3 | 1 | 17 |
| 4 | 1 | 12 |
| 1 | 2 | 13 |
| 2 | 2 | 8 |
| 3 | 2 | 15 |
| 4 | 2 | 16 |
| 1 | 3 | 9 |
| 2 | 3 | 14 |
| 3 | 3 | 9 |
| 4 | 3 | 10 |
| 1 | 4 | 15 |
| 2 | 4 | 16 |
| 3 | 4 | 9 |
| 4 | 4 | 12 |
+---------------+---------------+---------+
And I want to get the max score from puntaje column where evaluacion_ID is equal to 3, i want this value to be in the 'maxpuntaje 'column in the evaluaciones table, like an update , this is evaluaciones table:
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| fecha | date | NO | | NULL | |
| tipo | enum('P','E') | NO | | NULL | |
| maxpuntaje | int(11) | NO | | NULL | |
| clase_ID | int(10) unsigned | NO | | NULL | |
| evaluacion_ID | int(10) unsigned | NO | PRI | NULL | auto_increment |
+---------------+------------------+------+-----+---------+----------------+
both of the tables have the evaluacion_ID column
I've commented out WHERE conditions that limit the UPDATE and maximum puntaje value retrieval so that your query could be run for all evaluacion_ID. If you need it only for 3, remove the comment marks.
Using MySQL UPDATE JOIN syntax:
UPDATE evaluaciones e
LEFT JOIN (
SELECT evaluacion_ID, MAX(puntaje) maxpuntaje
FROM puntajes
-- WHERE evaluacion_ID = 3
GROUP BY evaluacion_ID
) p USING (evaluacion_ID)
SET maxpuntaje = p.maxpuntaje
-- WHERE e.evaluacion_ID = 3
I suspect you're looking for this query:
UPDATE evaluaciones
SET maxpuntaje = (
SELECT max(puntaje)
FROM puntajes
WHERE evaluacion_ID = evaluaciones.evaluacion_ID
)
WHERE evaluacion_ID = 3
Hi following are my 4 tables.
client_parent_question :-
+----+------------+------------+---------+-----+------+------+
| id | is_deleted | sort_order | version | cid | pid | qid |
+----+------------+------------+---------+-----+------+------+
| 1 | | 1 | 0 | 1 | 1 | 1 |
| 2 | | 2 | 0 | 1 | 1 | 2 |
| 3 | | 3 | 0 | 1 | 1 | 3 |
| 4 | | 4 | 0 | 1 | 1 | 4 |
| 5 | | 1 | 0 | 1 | 2 | 7 |
+----+------------+------------+---------+-----+------+------+
mysql> select * from client_parent;
+----+------------+------------+---------+-----+------+
| id | is_deleted | sort_order | version | cid | pid |
+----+------------+------------+---------+-----+------+
| 1 | | 1 | 0 | 1 | 1 |
| 2 | | 2 | 0 | 1 | 2 |
+----+------------+------------+---------+-----+------+
2 rows in set (0.00 sec)
mysql> select * from client_question;
+----+------------+---------+-----+------+------+
| id | is_deleted | version | cid | pqid | qtid |
+----+------------+---------+-----+------+------+
| 1 | | 0 | 1 | 1 | 1 |
| 2 | | 0 | 1 | 2 | 4 |
| 3 | | 0 | 1 | 2 | 4 |
| 4 | | 0 | 1 | 1 | 1 |
| 5 | | 0 | 1 | 2 | 4 |
| 6 | | 0 | 1 | 3 | 4 |
| 7 | | 0 | 1 | 3 | 4 |
| 8 | | 0 | 1 | 1 | 1 |
| 9 | | 0 | 1 | 2 | 4 |
| 10 | | 0 | 1 | 3 | 4 |
| 11 | | 0 | 1 | 4 | 4 |
| 12 | | 0 | 1 | 4 | 4 |
+----+------------+---------+-----+------+------+
mysql> select * from client_question_option;
+----+------------+---------+------+------+
| id | is_deleted | version | cqid | oid |
+----+------------+---------+------+------+
| 1 | | 0 | 2 | 1 |
| 2 | | 0 | 3 | 4 |
| 3 | | 0 | 6 | 2 |
| 4 | | 0 | 7 | 3 |
| 5 | | 0 | 11 | 1 |
| 6 | | 0 | 12 | 4 |
| 7 | | 0 | 14 | 1 |
| 8 | | 0 | 15 | 4 |
+----+------------+---------+------+------+
I know only cid and pid of client_parent table
My aim is to delete all from client_question,client_parent_question and client_question_option
In the client_question_option cqid id is the id of client_question table
Following is the sqlfiddle
I did
DELETE FROM cqo,qo,cpq client_question_option cqo ,client_question cq,client_parent_question ,client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=qo.id AND cq.cid=1 AND cp.pid=1
But this did not work.
You just need to move the FROM keyword after the table aliases. See multiple-table syntax
DELETE cqo, qo, cpq
FROM client_question_option cqo,
client_question cq,
client_parent_question,
client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=qo.id
AND cq.cid=1 AND cp.pid=1;
Your DELETE query's syntax is wrong, which must be somthing like this:-
DELETE cqo,cp,pq
FROM client_question_option cqo, client_question cq, client_parent_question pq, client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=cp.id AND cq.cid=1 AND cp.pid=1;
Hope this will help you.
using inner join
DELETE cqo,cq,cp,pq
FROM client_question_option cqo
INNER JOIN client_question cq
INNER JOIN client_parent_question as pq
INNER JOIN client_parent cp
WHERE cqo.cqid=cq.id AND cq.pqid=pq.id AND cqo.oid=cqo.id AND cq.cid=1 AND cp.pid=1
You have an option in MYSQL Called as ONDELETE CASCADE where in when you set this on a key
example : foreign key(cid) references client_parent(cid) ON DELETE CASCADE when you delete the key based on your condition all referencing ids will be deleted , so one simple query to delete parent row is enough for it to delete all child rows present in other table data
Advantages of using ON DELETE CASCADE
you are not require to right innerjoins and delete data manually
you dont get parent key errors
you can save up your time
Thats it NJOY!!!
I have a table named item with category ID and item IDs.
Item ID is the primary key and each item is related to category ID.
I want to retrieve 20 items, but 4 items for one category. If there aren't 4 items for
some category, then select all items from this category.
This is my query, it is not working:
SELECT * FROM `item`
JOIN (SELECT `item_id` FROM `item` GROUP BY `category_id` LIMIT 4) LIMIT 20;
my table stucture
item
item id | category id
----------------------------
1 | 1
2 | 1
3 | 2
4 | 2
5 | 1
6 | 3
if my table has
category
category | count(item)
-----------------------------
1 | 5
2 | 3
3 | 10
4 | 8
5 | 12
6 | 6
7 | 6
8 | 6
I want to select 20 items like that
category items from this category
----------
1 | 4
2 | 3
3 | 4
4 | 4
5 | 4
6 | 1
You can try this query
SET #level = 0;
SET #group = '';
SELECT
item_id,
category_id
FROM (
SELECT
item_id,
category_id,
#level := IF(#group = category_id, #level+1, 1) AS level,
#group := category_id as EGroup
FROM item
ORDER BY category_id
) rs
WHERE level < 5
Here is some sample data
| ID | ITEM_ID | CATEGORY_ID |
|----|---------|-------------|
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 4 | 4 | 1 |
| 5 | 5 | 1 |
| 6 | 6 | 2 |
| 7 | 7 | 2 |
| 8 | 8 | 2 |
| 9 | 9 | 2 |
| 10 | 10 | 3 |
| 11 | 11 | 3 |
| 12 | 12 | 3 |
| 13 | 13 | 3 |
| 14 | 14 | 3 |
| 15 | 15 | 3 |
| 16 | 16 | 4 |
| 17 | 17 | 4 |
| 18 | 18 | 5 |
| 19 | 19 | 5 |
| 20 | 20 | 5 |
| 21 | 21 | 5 |
| 22 | 22 | 5 |
| 23 | 23 | 6 |
| 24 | 24 | 7 |
| 25 | 25 | 7 |
Output
| ITEM_ID | CATEGORY_ID |
|---------|-------------|
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 9 | 2 |
| 8 | 2 |
| 7 | 2 |
| 6 | 2 |
| 15 | 3 |
| 14 | 3 |
| 13 | 3 |
| 12 | 3 |
| 16 | 4 |
| 17 | 4 |
| 22 | 5 |
| 21 | 5 |
| 20 | 5 |
| 19 | 5 |
| 23 | 6 |
| 24 | 7 |
| 25 | 7 |
SQL Fiddle Demo