Help with a MySQL query - mysql

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.

Related

How to assign user to group in 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.

chaning the join in mysql

I have 2 tables, faq and faq_categories...i have a join that work, and so far, I was a happy camper.
But...requirements change, and i have to change the join, but i don't know how to do it
Here is the current code that works just fine:
SELECT faq.* , faq_categories.categoryname
FROM faq
JOIN faq_categories
ON ( faq.catid = faq_categories.catid)
So far, all faq belongs to one category...but from now on, there will be faq which will not belonng to any category....and that complicate things, at least for me.
How should I change this code in order to display the faq which does not have catid?
Here are my tables:
CREATE TABLE IF NOT EXISTS `faq_categories` (
`catid` int(11) NOT NULL AUTO_INCREMENT,
`parentid` int(11) DEFAULT NULL,
`categoryname` varchar(255) NOT NULL,
`categoryname_en` varchar(255) DEFAULT NULL,
`description` text,
`description_en` text,
`metatags` text,
`metatags_en` text,
`sorder` int(11) NOT NULL,
`visible` tinyint(4) NOT NULL,
`categoryphoto` varchar(255) DEFAULT '',
PRIMARY KEY (`catid`),
KEY `parentid_fk` (`parentid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=204 ;
CREATE TABLE IF NOT EXISTS `faq` (
`faqid` int(11) NOT NULL AUTO_INCREMENT,
`catid` int(11) DEFAULT NULL,
`question` text NOT NULL,
`question_en` text NOT NULL,
`answer` text,
`answer_en` text,
`metatags` text,
`metatags_en` text,
`sorder` tinyint(4) DEFAULT NULL,
`visible` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`faqid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;
For those that have no category, we assume you mean faq.catid will be NULL. Your table definitions don't need to change at all. That will only require changing yourINNER JOINto aLEFT JOIN. The FAQs with no category will show aNULLforfaq_categories.categoryname` in the output:
SELECT
faq.* ,
faq_categories.categoryname
FROM
faq
LEFT JOIN faq_categories ON ( faq.catid = faq_categories.catid)
I would encourage you now to anticipate the time when a FAQ must belong to more than one category, however. To do that, you need to create a joining table which contains a faqid and catid. There can be many rows per faqid:
CREATE TABLE faq_in_categories (
faqid INT(11) NOT NULL,
catid INT(11) NOT NULL,
PRIMARY KEY (faqid, catid),
FOREIGN KEY (faqid) REFERENCES faq (faqid),
FOREIGN KEY (catid) REFERENCES faq_categories (catid)
);
Under this model, you would remove the faq.catid column because membership in a category is defined in the joining table. This is a many-to-many relationship.
Queried by:
SELECT
faq.*
categories.*
FROM
faq
JOIN faq_in_categories ON faq.faqid = faq_in_categories.faqid
JOIN categories ON faq_in_categories.catid = categories.catid
WHERE faq.faqid = 'some faqid'

How can I select the current holder for each championship?

I want to select the current holders for each championship in a championships table, and return NULL for championships that have not had any winners yet.
Here are the create statements for the two tables:
CREATE TABLE `championships` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`friendly_name` varchar(255) NOT NULL,
`rank` int(2) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `friendly_name` (`friendly_name`)
) ENGINE=InnoDB;
CREATE TABLE `title_history` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`championship` int(10) unsigned NOT NULL,
`winner` varchar(255) NOT NULL,
`date_from` date NOT NULL,
`location` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `championship` (`championship`)
) ENGINE=InnoDB;
ALTER TABLE `title_history` ADD CONSTRAINT `title_history_ibfk_1` FOREIGN KEY (`championship`) REFERENCES `championships` (`id`) ON UPDATE CASCADE;
What MySQL statement would return the data set I wanted?
Assuming you're storing the winner of a championship as the primary key/id of the holder, something like this should work. You might want to add in another join to get the actual name of the team from another table though.
Because LEFT join will only select rows from the 'right' table when there is a match, everything that doesn't have one should come back as NULL.
SELECT name, [holder]
FROM championships AS c
LEFT JOIN title_history AS h ON c.winner = h.id
EDITED VERSION:
With further insight into your tables and from your comment, maybe try this subselect:
SELECT friendly_name,
(SELECT winner FROM title_history WHERE championship = c.id ORDER BY date_from DESC LIMIT 1)
FROM championships AS c
ORDER BY name
If I understand your structure correctly, that ought to get the last winner of each championship?

mysql aggregate difficulties

I have two table structures in my database:
CREATE TABLE `projects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
`description` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
CREATE TABLE `issues` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`member_id` varchar(10) DEFAULT NULL,
`project_id` int(11) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL,
`description` varchar(128) DEFAULT NULL,
`date_created` date DEFAULT NULL,
`type` enum('general','bug','requirement') DEFAULT NULL,
`priority` enum('low','medium','high') DEFAULT NULL,
`status` enum('resolved','open','discarded') DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `member_id` (`member_id`),
KEY `project_id` (`project_id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
What I am trying to do is create a select statement that returns the project name, and the number of resolved issues that are associated with that project. I have created the following SQL statement:
select projects.name, count(*) from projects left join issues on projects.id = issues.project_id where status = 'resolved' group by projects.name
However this only returns projects that have at least one resolved issue, I need it to return projects that have 0 resolved issues as well.
It's been a while since I have done any mySQL, can anyone help out? Thanks.
I thought I'd give some more information since I haven't received a working answer yet. If I had four projects and one issue for each project, with two of those issues being 'resolved', I'd expect the query to return:
project_name | count(*)
--------------------------
first_project | 1
second_project | 0
third_project | 0
fourth_project | 1
However, the query is only returning projects that have at least one resolved issue.
project_name | count(*)
-------------------------
first_project | 1
fourth_project | 1
change your query to:
SELECT p.name, count(i.*)
FROM PROJECTS p
LEFT JOIN ISSUES i ON p.id = i.project_id
AND i.status = 'resolved'
GROUP BY projects.name
having "status = 'resolved'" in the where clause caused it only to return those projects with at least one issue

Mysql query generation

This is my user table schema
CREATE TABLE IF NOT EXISTS `ehobe_user` (
`user_id` bigint(20) NOT NULL,
`user_email` varchar(80) NOT NULL,
`user_password` varchar(50) NOT NULL,
`user_fname` varchar(255) NOT NULL,
`user_lname` varchar(255) NOT NULL,
`user_terms` enum('yes','no') NOT NULL DEFAULT 'yes',
`is_active` enum('yes','no') NOT NULL DEFAULT 'yes',
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
And this is my friends table schema
CREATE TABLE IF NOT EXISTS `ehobe_friends` (
`user_id1` bigint(20) NOT NULL,
`user_id2` bigint(20) NOT NULL,
`relationship_id` int(1) NOT NULL COMMENT '1 - user1 request, 2- user2 request, 3 - friends, 4- user1 blocked, 5 - user2 blocked'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
So i need to select the user first name and last name who are my frinds in the friends table.
Suppose you want friends of USER_ID #67.
Try:
select u.user_id, u.user_fname, u.user_lname
from ehobe_user u
inner join ehobe_friends f1 on (u.user_id = f1.user_id1)
where f1.user_id2 = 67
union
select u.user_id, u.user_fname, u.user_lname
from ehobe_user u
inner join ehobe_friends f2 on (u.user_id = f2.user_id2)
where f2.user_id1 = 67
Logically, you want to get all of the friends in an array and check each user for matching info. I would give you code, but I don't know what language you're writing this in.