How to assign user to group in MySQL? - mysql

I have two tables in MySQL database one is named 'users' the other is 'groups'.
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`full_name` varchar(50) NOT NULL DEFAULT '',
`position` varchar(50) NOT NULL DEFAULT '',
`company` varchar(50) NOT NULL DEFAULT '',
`email` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
)
CREATE TABLE `groups` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`group_name` varchar(30) NOT NULL
PRIMARY KEY (`id`)
)
How do I assign a user to a group? I was thinking of joining the tables together but I don't know how to start? I am open to try this another way if joining tables is complex.

You need to create a bridge table like below and insert users.id and groups.id in to that table.
Users_group (userid,groupid)
If one user can belong to multiple groups, you can make userid and groupid as composite primary key
Assuming you are trying to insert the users and group combinations.

Related

MySQL filtering result from a foreign key that doesn't have contents

i have two tables:
CREATE TABLE IF NOT EXISTS `test_category` (
`_id` int(11) NOT NULL AUTO_INCREMENT,
`score_type` varchar(50) NOT NULL,
`sub_code` int(11) NOT NULL,
`duration` varchar(10) NOT NULL,
`status` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`_id`),
KEY `sub_code` (`sub_code`)
)
CREATE TABLE IF NOT EXISTS `questions` (
`_id` int(11) NOT NULL AUTO_INCREMENT,
`question` varchar(255) NOT NULL,
`correct_ans` varchar(255) NOT NULL,
`incorrect1` varchar(255) NOT NULL,
`incorrect2` varchar(255) NOT NULL,
`incorrect3` varchar(255) NOT NULL,
`test_cat` int(11) NOT NULL,
`image_location` varchar(50) NOT NULL,
PRIMARY KEY (`_id`),
KEY `test_cat` (`test_cat`)
)
ALTER TABLE `questions`
ADD CONSTRAINT `questions_ibfk_1` FOREIGN KEY (`test_cat`) REFERENCES `test_category` (`_id`);
so basically these two tables are related. questions table is related to test_category table through the foreign key test_cat from the table questions referenced to the _id of test_category. what i wan't to display is those entry from test_category that have a entries related to it from the questions table. if an entry from test_category doesn't have anything referenced to it from the questions table then it shouldn't be displayed.
select distinct test_category._id, test_category.score_type
from test_category join questions
where ??
that's the sql i have tried but i don't know how to filter it with where...
select distinct test_category._id, test_category.score_type from test_category
join questions
on 'questions.test_cat' = 'test_category._id'
select distinct test_category._id, test_category.score_type from test_category
join questions
on questions.test_cat = test_category._id
kudos to Nisha and Abhik Chakraborty

Very slow mysql query for reading orders (joins and group by)

A query for reading orders is very slow. I've tried a lot of things, but couldn't get a faster query. Below the query and the database tables. Of course, all the important fields have an index. I noticed that removing the group by function will speed it up, but grouping the query is important.
is there a better way for getting the orders? Thanks in advance.
SELECT
orders.id AS orderId, orders.delivery_from, orders.delivery_to,
orders_products.product_id, orders_products.color_id, ,orders_products.size_id,
sum(orders_products.quantity) as quantity,
customers.id AS customerId, customers.name AS customerName,
products.name
FROM orders
INNER JOIN orders_products ON orders_products.order_id=orders.id
INNER JOIN customers ON customers.id=orders.customer_id
INNER JOIN products ON orders_products.product_id=products.id
LEFT JOIN orders_product_data ON orders_product_data.order_id=orders.id AND orders_product_data.product_id=orders_product.product_id AND orders_product_data.color_id=orders_product.color_id
WHERE orders.status='0' AND
(orders.delivery_from<='2014-05-05' AND orders.delivery_to>='2014-05-05') AND
((orders_products_data.delivery_from<='2014-05-05' || orders_products_data.delivery_to=0) AND (orders_products_data.delivery_from>='2014-05-05' || orders_products_data.delivery_to=0))
GROUP BY customer_id, product_id, color_id, size_id
Customers
CREATE TABLE IF NOT EXISTS `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(90) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);
Products
CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
);
Orders
CREATE TABLE IF NOT EXISTS `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(11) NOT NULL,
`delivery_from` date NOT NULL,
`delivery_to` date NOT NULL,
`status` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
Products of the order
CREATE TABLE IF NOT EXISTS `orders_products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` int(11) NOT NULL DEFAULT '0',
`product_id` int(11) NOT NULL DEFAULT '0',
`color_id` int(11) NOT NULL DEFAULT '0',
`size_id` int(11) NOT NULL DEFAULT '0',
`quantity` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
Color data. The tabel below stores for the combination order_id, product_id and color_id the delivery information since the delivery of products in different colors could change.
CREATE TABLE IF NOT EXISTS `orders_products_data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` int(11) NOT NULL DEFAULT '0',
`product_id` int(11) NOT NULL DEFAULT '0',
`color_id` int(11) NOT NULL DEFAULT '0',
`delivery_from` date NOT NULL,
`delivery_to` date NOT NULL,
PRIMARY KEY (`id`)
);
The explain query
You have mentioned that you have indexes for all the important fields.
Just for your Info - Index should be prepared based on the access path rather than for important fields.
Check after replacing delivery_from between '...' and '...' for orders, orders_product_data and adding following index:
create index idx_orders_status_delivery_from_to on orders(status,delivery_from,delivery_to);

how to create a view from three tables

I have problem with getting combined records from 3 tables.
Here is the structure of the tables
CREATE TABLE IF NOT EXISTS `adds` (
`addid` int(11) NOT NULL AUTO_INCREMENT,
`addtypeid` varchar(45) NOT NULL,
`addcreatedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`addtitle` varchar(255) DEFAULT NULL,
`addtext` text NOT NULL,
PRIMARY KEY (`addid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=40 ;
CREATE TABLE IF NOT EXISTS `adds_filters` (
`addfilterid` int(11) NOT NULL AUTO_INCREMENT,
`addid` int(11) NOT NULL,
`filterid` int(11) NOT NULL,
PRIMARY KEY (`addfilterid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=40 ;
CREATE TABLE IF NOT EXISTS `categories_filters` (
`filterid` int(11) NOT NULL AUTO_INCREMENT,
`catid` varchar(45) NOT NULL,
`filtername` varchar(45) NOT NULL,
`sorder` int(11) DEFAULT NULL,
`visible` int(11) DEFAULT NULL,
PRIMARY KEY (`filterid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=230 ;
Adds have one to many relationship with adds_filters. That is, one add can have more then one filter.
What I need is the following:
I would like to create a view which when select * would return all rows from adds, together with filterid(s) and respective filtername(s). Please note that one add may have many filterid(s)
Can anyone help me with this?
Regards
You do not need a view.
I think you want to use a combination of LEFT OUTER JOIN and GROUP_CONCAT(). That way you will get 1 result for each row in the adds table, along with a list of related filter_ids and filter_names, if any.
Something like this:
select adds.addid, adds.addtypeid, adds.addcreatedon, adds.addtitle, adds.addtext,
group_concat(adds_filters.filterid) as filter_ids,
group_concat(categories.filtername) as filter_names
from adds
left outer join adds_filters on adds_filters.addid = adds.addid
left outer join categories_filters on categories_filters.filterid = adds_filters.filterid
group by adds.addid, adds.addtypeid, adds.addcreatedon, adds.addtitle, adds.addtext;
create view v1 as
select adds.addid as addid, categories_filters.filtername as filtername, categories_filters.filterid as filterid
from adds inner join adds_filters on adds.addid = adds_filters.addid
inner join categories_filters on categories_filters.filterid = adds_filters.filterid

mySQL view for two different tables?

I've a massive problem creating a view in mySQL:
Table A in database DB1:
CREATE TABLE `a` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'internal ID',
`account` VARCHAR(10) NOT NULL DEFAULT '0',
`filename` VARCHAR(50) NOT NULL,
`filesize` BIGINT(15) NOT NULL DEFAULT '0'
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
Table B in database DB2:
CREATE TABLE `b` (
`archive_id` INT(10) UNSIGNED NULL AUTO_INCREMENT,
`archive_datetime` DATETIME,
`id` INT(10) UNSIGNED NOT NULL,
`account` VARCHAR(10) NOT NULL DEFAULT '0',
`filename` VARCHAR(50) NOT NULL,
`filesize` BIGINT(15) NOT NULL DEFAULT '0'
PRIMARY KEY (`archive_id`)
)
ENGINE=Archive
Entries from table A are automatically transfered to table B via trigger if BEFORE DELETE.
I need a view that gives me all entries from table a and table b as if they were still in one table of the same database. Columns archive_id and archive_datetime can be ignored in the view as they are not needed for this scenario.
You could use UNION:
SELECT * FROM a UNION SELECT * FROM b;
You just have to replace * with the desired table columns.
SELECT id, account, filename, filesize FROM a UNION ALL SELECT id, account, filename, filesize FROM b
Surely I must be missing something?

Help with a MySQL query

I have the following query:
SELECT u.uid, pf.title, pv.value FROM users AS u INNER JOIN
profile_values AS pv ON pv.uid = u.uid
INNER JOIN
profile_fields AS pf ON pf.fid = pv.fid
ORDER BY u.uid
Which results in:
uid title value
1 First name Jared
1 Last name Boo
1 Organization Acme
1 Website http://acme.com
1 Country Canada
6 First name Nathan
6 Last name Foo
I am attempting to use this result to create another result set which looks like this:
uid First name Last name Organization Website Country
1 Jared Boo Acme http... Canada
6 Nathan Foo
Am I going about this correctly?
Thanks in advance
EDIT
Tables:
CREATE TABLE `users` (
`uid` int(10) unsigned NOT NULL auto_increment,
`name` varchar(60) NOT NULL default '',
`pass` varchar(32) NOT NULL default '',
`mail` varchar(64) default '',
`created` int(11) NOT NULL default '0',
`access` int(11) NOT NULL default '0',
PRIMARY KEY (`uid`),
UNIQUE KEY `name` (`name`),
KEY `access` (`access`),
KEY `created` (`created`),
KEY `mail` (`mail`)
);
CREATE TABLE `profile_fields` (
`fid` int(11) NOT NULL auto_increment,
`title` varchar(255) default NULL,
`name` varchar(128) NOT NULL default '',
`explanation` text,
`category` varchar(255) default NULL,
PRIMARY KEY (`fid`),
UNIQUE KEY `name` (`name`),
KEY `category` (`category`)
);
CREATE TABLE `profile_values` (
`fid` int(10) unsigned NOT NULL default '0',
`uid` int(10) unsigned NOT NULL default '0',
`value` text,
PRIMARY KEY (`uid`,`fid`),
KEY `fid` (`fid`)
);
SELECT u.uid, pf.title, pv.value
FROM users AS u, profile_values AS pv, profile_fields AS pf
WHERE pv.id = u.uid, pf.fid = pv.fid
ORDER BY u.uid
Is something like this what your looking for? What do the tables look like in terms of foreign keys? You may want to throw a DISTINCT in right after SELECT.
This is all correct. It is not clear where organization, Website, Country fields should come from (as we don't know your database structure), but, for example, if country was a column of profile_fields, you would simply add SELECT ..., pf.country ... to get the desired data.
It seems like your schema is not accurately maintaining the required information. First off in the User table you have name as 1 attribute, thus splitting first and last name must be done by some other means. Secondly it is not clear where the company name or website information is stored. Please provide a logical mapping from the desired output to the attributes in the database tables.