Writing a SQL Query - mysql

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.

Related

mysql query to find all possible like combinations start with and ends with (simplified duplicate)

-- Sample data, borrowed from https://stackoverflow.com/q/7745609/808921
CREATE TABLE IF NOT EXISTS `docs` (
`id` int(6) NOT NULL auto_increment,
`groupname` varchar(100),
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `sm` (
`id` int(6) NOT NULL auto_increment,
`code` varchar(100),
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `docs` (`groupname`) VALUES
('100:2000'),
('100:2001'),
('101:2000'),
('101:2001'),
('102:2002'),
('103:2003');
INSERT INTO `sm` (`code`) VALUES
('100'),
('101'),
('2000');
SQL Fiddle of same: http://sqlfiddle.com/#!9/54714e/39
In MySQL, I would like to filter only the group names that contains various combinations of values in the sm table. i.e. 100,101,2000.
The below query returns other combinations too like
100:2000
100:2001
101:2000
101:2001
SQL:-
select distinct d.groupname from docs d, sm s where d.groupname like concat(s.code,'%') or d.groupname like concat('%',s.code);
Original question:-
mysql query to find all possible like combinations start with and ends with
Update:-
Expected results:-
100:2000
101:2000
I've just broke your or condition into make multiple join with the same table like below to achieve your expected result,
select distinct d.groupname from docs d
join sm s1 on
d.groupname like concat(s1.code,'%')
join sm s2 on
d.groupname like concat('%',s2.code);

MySQL selecting a column from another table

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

JOIN databases from SELECT

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

Mysql query to get detail of comma-separated ids data

I have 2 tables, items and members :
CREATE TABLE IF NOT EXISTS `items` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`member` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `members` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
What if, for example I have a record inside items, such as
INSERT INTO `test`.`items` (
`id` ,
`name` ,
`member`
)
VALUES (
NULL , 'xxxx', '1, 2, 3'
);
in members :
INSERT INTO `members` (`id`, `name`) VALUES
(1, 'asdf'),
(2, 'qwert'),
(3, 'uiop'),
(4, 'jkl;');
and I'd like to display items.member data with members.name, something like 1#asdf, 2#qwert, 3#uiop??
I've tried the following query,
SELECT items.id, items.name, GROUP_CONCAT(CONCAT_WS('#', members.id, members.name) ) as member
FROM `items`
LEFT JOIN members AS members on (members.id = items.member)
WHERE items.id = 1
But the result is not like I expected. Is there any other way to display the data via one call query? Because I'm using PHP, right now, i'm explode items.member and loop it one by one, to display the members.name.
You could look into using FIND_IN_SET() in your join criteria:
FROM items JOIN members ON FIND_IN_SET(members.id, items.member)
However, note from the definition of FIND_IN_SET():
A string list is a string composed of substrings separated by “,” characters.
Therefore the items.member column should not contain any spaces (I suppose you could use FIND_IN_SET(members.id, REPLACE(items.member, ' ', '')) - but this is going to be extremely costly as your database grows).
Really, you should normalise your schema:
CREATE TABLE memberItems (
item_id INT(5) NOT NULL,
member_id INT(5) NOT NULL,
FOREIGN KEY item_id REFERENCES items (id),
FOREIGN KEY member_id REFERENCES members (id)
);
INSERT INTO memberItems
(item_id, member_id)
SELECT items.id, members.id
FROM items
JOIN members ON FIND_IN_SET(members.id, REPLACE(items.member,' ',''))
;
ALTER TABLE items DROP member;
This is both index-friendly (and therefore can be queried very efficiently) and has the database enforce referential integrity.
Then you can do:
FROM items JOIN memberItems ON memberItems.item_id = items.id
JOIN members ON members.id = memberItems.member_id
Note also that it's generally unwise to use GROUP_CONCAT() to combine separate records into a string in this fashion: your application should instead be prepared to loop over the resultset to fetch each member.
Please take a look at this sample:
SQLFIDDLE
Your query seems to work for what you have mentioned in the question... :)
SELECT I.ID, I.ITEM,
GROUP_CONCAT(CONCAT("#",M.ID,
M.NAME, " ")) AS MEMB
FROM ITEMS AS I
LEFT JOIN MEMBERS AS M
ON M.ID = I.MID
WHERE i.id = 1
;
EDITTED ANSWER
This query will not work for you¬ as your schema doesn't seem to have any integrity... or proper references. Plus your memeber IDs are delimtted by a comma, which has been neglected in this answer.

mysql left join question

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