I'm trying to pull information from a second table (particularly, the class column). I have two tables:
CREATE TABLE `tags` (
`Tag` varchar(255) NOT NULL,
`class` tinytext NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Dumping data for table `tags`
--
INSERT INTO `tags` (`Tag`, `class`) VALUES
('Arya', 'label-default'),
('bull', 'label-info'),
('Cats', 'label-default'),
('Floki', 'label-default'),
('Overwatch', 'label-info'),
('Ragnar', 'label-default');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `tags`
--
ALTER TABLE `tags`
ADD PRIMARY KEY (`Tag`);
CREATE TABLE `post_tags` (
`ID` int(11) NOT NULL,
`PostID` int(11) NOT NULL,
`tagID` tinytext NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `post_tags`
--
INSERT INTO `post_tags` (`ID`, `PostID`, `tagID`) VALUES
(1, 27, 'Cats'),
(2, 27, ' Ragnar'),
(3, 27, ' Floki'),
(4, 27, ' Arya');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `post_tags`
--
ALTER TABLE `post_tags`
ADD PRIMARY KEY (`ID`);
Goal:
| Tag | class
|--------|--------------
| Cats | label-info
| Ragnar | label-default
| Arya | label-danger
| Floki | label-info
I've tried using this Query, but only one row is being returned:
SELECT * FROM `tags` WHERE `Tag` IN
(SELECT `tagID` FROM `post_tags` WHERE `post_tags`.`PostID` = 27)
In your actual dataset above the post_tags table contains rows beginning with space character in TagID column: Ragnar, Floki and Arya except Cats. But Tag column of tags table contains these items without beginning space.
Because of this only the Cats is displayed in the result. So either remove manually spaces from TagID or remove them in SQL query with TRIM function:
SELECT a.Tag, a.class FROM tags AS a LEFT JOIN post_tags AS b ON TRIM(b.tagID) = TRIM(a.Tag) WHERE b.PostID = "27"
Hope this helps
i thing you have problems with the manes you put to your columns:
but you can running the following script
select a.PostID,
b.Tag,
b.class
from post_tags a
inner join tags b on a.tagID=b.Tag
where a.PostID=27
Related
Suppose the schemas are
users(id, name)
users_attributes(user_id, attribute_name, attribute_value)
Sample data:
--
-- Database: `sample_db`
--
CREATE DATABASE IF NOT EXISTS `sample_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `sample_db`;
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `name`) VALUES
(1, 'Tim'),
(2, 'Joe'),
(3, 'Bob');
-- --------------------------------------------------------
--
-- Table structure for table `users_attributes`
--
CREATE TABLE `users_attributes` (
`user_id` int(11) NOT NULL,
`attribute_name` varchar(50) NOT NULL,
`attribute_value` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `users_attributes`
--
INSERT INTO `users_attributes` (`user_id`, `attribute_name`, `attribute_value`) VALUES
(1, 'height', '10'),
(1, 'over_18', 'yes'),
(2, 'height', '5'),
(3, 'height', '7');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`id`);
--
-- Indexes for table `users_attributes`
--
ALTER TABLE `users_attributes`
ADD UNIQUE KEY `user_id` (`user_id`,`attribute_name`,`attribute_value`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
COMMIT;
Right now I'm calling INNER JOIN on a specific attribute_name so my selection also returns that along with the user id and name. Now I want to exclude from whatever I selected, if they contain a certain other attribute. I know I can accomplish that by using a NOT IN (SELECT ...) conditional but can I do that without having to select again?
EDIT:
Attributes may or may not exist for all users. For example, I would like to fetch id, name, attribute_value where attribute_name = height but only if attribute_name over_18 does not exist or is 'no'
I need a joined (Union like) result from multiple databases on the same databaseserver in one query. Every customer database contains a location table and all customers are listed in the core database.
I don't need a simple join between to different databases. I need the actual joined database name to come from the same query.
I figure something like this.
SELECT customerlist.dbname,customerlist.realname,location.address
FROM core.customerlist
INNER JOIN `customer.dbname`.location
ORDER BY customerlist.realname
I know this won't work, I'm just trying to pseudo code what I'm searching for. I hope someone can help.
Database structure:
-- Database: `core`
CREATE TABLE IF NOT EXISTS `customerlist` (
`realname` varchar(20) NOT NULL,
`dbname` varchar(16) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `customerlist` (`realname`, `dbname`) VALUES
('Johnny', 'johnny'),
('Alfred', 'alfred');
-- --------------------------------------------------------
-- Database: `alfred`
CREATE TABLE IF NOT EXISTS `location` (
`address` varchar(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `location` (`address`) VALUES
('House Three'),
('Car 1');
-- --------------------------------------------------------
-- Database: `johnny`
CREATE TABLE IF NOT EXISTS `location` (
`address` varchar(20) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `location` (`address`) VALUES
('House One'),
('House Two');
Desired result;
johnny,Johnny,House One
johnny,Johnny,House Two
alfred,Alfred,House Three
alfred,Alfred,Car 1
You'll have to be careful of the two table identical tables...joining them in a union if fine since they are identical in structure:
SELECT customerlist.dbname,customerlist.realname,location.address
FROM core.customerlist
LEFT JOIN (
SELECT * FROM (johnny.location UNION alfred.location
)) AS T2 ON customerlist.dbname = T2.dbname
ORDER BY customerlist.realname
I want make query select all names from table 'a' where from table 'b' i have id_one='3'. id_two is id record from table
'a', two records have relation from id_one='3'. How i can make query ?
CREATE TABLE IF NOT EXISTS `a` (
`id` int(11) NOT NULL,
`name` varchar(11) NOT NULL,
`value` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Zrzut danych tabeli `a`
--
INSERT INTO `a` (`id`, `name`, `value`) VALUES
(1, 'lalala', 0),
(2, 'allalala', 0);
CREATE TABLE IF NOT EXISTS `b` (
`id_one` int(11) NOT NULL,
`id_two` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Zrzut danych tabeli `b`
--
INSERT INTO `b` (`id_one`, `id_two`) VALUES
(3, 1),
(3, 2);
This is what you want:
select Name
from a inner join b on a.id = b.id_two
where b.id_one = 3
sorry I'm not fully understanding your schemas or your question, but I think what you're trying to ask for is:
SELECT * FROM a
JOIN b on a.id = b.id_two;
Try that.
Your question title mentions left joins, but you don't need a left join to make the query you described.
Left joins are good for finding things that don't match up the way you'd expect. So, using a left join in this case depends on what you are looking for. If you are looking for b.id_two entries that don't have corresponding table a entries,
select Name, b.* from b left join a on a.id = b.id_two
This will give you a table that lists every row in table b, with NULLs in place of the names for table a where there is no match.
Likewise, if you are looking for names that don't have entries in b.id_two, you would use
select Name, b.* from a left join b on a.id = b.id_two
If you want to enforce that there is always a correspondence, you can define a foreign key constraint between the parent and child table.
select Name
from a join b on a.id = b.id_two
where b.id_one = 3;
Will also work to get your answer. Might I also suggest you significantly improve your create table statements to include indexing. E.G.
CREATE TABLE IF NOT EXISTS `a` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(11) NOT NULL,
`value` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `b` (
`id_one` bigint(20) NOT NULL,
`id_two` bigint(20) NOT NULL,
KEY `FKCAFBB09382DEAC` (`id_one`),
CONSTRAINT `b_a_1` FOREIGN KEY (`id_two`) REFERENCES `a` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I would also use bigint for primary keys and use charset=utf8
these days it is just to common to want to migrate application to multi-lingual, lay the ground work now. IMHO
I have two tables:
product_description( name , product_id)
product( quantity, stock_status_id, price, product_id)
What I am trying to do is run a query that will get me the above data but I am not sure how to implement a join to get the joined data from both tables.
Resolved
I did the following:
SELECT product_description.name, product.quantity,product.price
FROM product
INNER JOIN product_description
ON product.product_id=product_description.product_id
ORDER BY product_description.name
Operating under the assumption that you have matching product_ids in each table, here's a query that will return the data you need using implicit joins:
SELECT product.product_id, name, quantity, stock_status_id, price
FROM product, product_description
WHERE product.product_id = product_description.product_id
UPDATE:
This works as I would expect. Here are two table dumps that might help you, and the output of the query.
product table:
--
-- Table structure for table `product`
--
CREATE TABLE IF NOT EXISTS `product` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(256) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
--
-- Dumping data for table `product`
--
INSERT INTO `product` (`product_id`, `name`) VALUES
(1, 'Croissant'),
(2, 'Danish');
product_description table:
--
-- Table structure for table `product_description`
--
CREATE TABLE IF NOT EXISTS `product_description` (
`product_id` int(11) NOT NULL,
`quantity` int(11) NOT NULL,
`stock_status_id` int(11) NOT NULL,
`price` double NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
--
-- Dumping data for table `product_description`
--
INSERT INTO `product_description` (`product_id`, `quantity`, `stock_status_id`, `price`) VALUES
(1, 6, 2, 12.5),
(2, 13, 1, 19.25);
Output from the above query:
"1","Croissant","6","2","12.5"
"2","Danish","13","1","19.25"
maybe something like this?
select p.id, p.quantity, p.stock_status_id, p.price, d.name
from Product p inner join `Product Description` d on d.product_id=p.id
although I'm still not sure of what the table schema actually looks like from the description in the question.
SELECT
-- name each column you want here
-- prefix columns from the PRODUCT table with its alias like so:
p.product_id,
-- prefix columns from the other table as its alias
d.quantity
FROM
PRODUCT p -- name of your PRODUCT table aliased as p
INNER JOIN -- join against your other table
PRODUCT_DESCRIPTION d -- name of your other table aliased as d
ON
p.product_id = d.product_id -- match the foreign keys
See INNER JOIN documentation for more details.
NOTE: This won't work as-is, you'll need to provide the columns that you want from each table in the SELECT clause, and probably fix the table names to match for your application.
Dears,
I need your help to optimize the below query. I have two tables, one for storing books data and the second table for mapping the books to tags related to it. I want to count how many books form a certain publisher in every category. This query do the job but I need to optimize it:
select count(book.id),publisher from book,tag where book.id=tag.book_id AND publisher ='Addison-Wesley Professional' AND tag.name='PHP' group by category
the result of explain is
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tag ref PRIMARY PRIMARY 92 const 1 Using where; Using index; Using temporary; Using f...
1 SIMPLE book eq_ref PRIMARY PRIMARY 4 test.tag.book_id 1 Using where
the tables are:
--
-- Table structure for table `book`
--
CREATE TABLE `book` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(30) NOT NULL,
`ISBN` varchar(10) NOT NULL,
`category` varchar(30) NOT NULL,
`publisher` varchar(30) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `book`
--
INSERT INTO `book` VALUES (1, 'PHP and MySQL Web Development', '9780672329', 'Web Development', 'Addison-Wesley Professional');
INSERT INTO `book` VALUES (2, 'JavaScript Patterns', '0596806752', 'Web Development', 'O''Reilly Media');
--
-- Table structure for table `tag`
--
CREATE TABLE `tag` (
`name` varchar(30) NOT NULL,
`book_id` int(11) NOT NULL,
PRIMARY KEY (`name`,`book_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Dumping data for table `tag`
--
INSERT INTO `tag` VALUES ('MySQL', 1);
INSERT INTO `tag` VALUES ('PHP', 1);
You need a composite index on (publisher, category) in your book table, in that exact order, so the subquery doing grouping on category can restrict results fast to those having exact publisher and then use second part of the index to group on category.
ALTER TABLE book ADD INDEX publ_cat( publisher, category );