MYSQL join two tables - php

I have two tables one containing a selection of values in different categories and the other ‘master’ table referencing the text values by the first primary key.
Table 1
CREATE TABLE IF NOT EXISTS `defaultvalues` (
`default_ID` int(11) NOT NULL AUTO_INCREMENT,
`columnName` varchar(100) NOT NULL,
`defaultValue` varchar(100) NOT NULL,
PRIMARY KEY (`default_ID`),
UNIQUE KEY `columnName` (`columnName`,`defaultValue`)
)
Table 2
CREATE TABLE IF NOT EXISTS `master` (
`master_ID` int(11) NOT NULL AUTO_INCREMENT,
`size` int(11) NOT NULL,
`madeby` int(11) NOT NULL,
`type` int(11) NOT NULL,
`colour` int(11) NOT NULL,
`notes` text NOT NULL,
`issueDate` datetime NOT NULL,
`ceMark` text NOT NULL,
`batchNumber` text NOT NULL,
PRIMARY KEY (master_ID)
)
The master.size for each row is a P.key in the defaultvalues table.
E.g. master.colour = 234, 234=defaultvalues.defaultValue = ‘red’
E.g. master.size = 345, 345=defaultvalues.defaultValue = ‘small’
Now I would like to run a query that returns the ‘master’ table with text values in columns colour, size, type, madeby from ‘defaultvalues. defaultValue’ and ready for further processing.
I have been trying with sub queries and temp tables but I can’t get it to work
The current system relies on PHP and multiple queries and building arrays.
There has to be a more elegant solution.
I hope this makes sense.
Any hints or advice much appreciated.
Dave

You'll need to join the master table to the defaultvalues table multiple times. Something like this:
SELECT m.*, d.defaultvalue as sizevalue, d2.defaultvalue as colorvalue...
FROM master m
JOIN defaultvalues d ON m.size = d.default_id
JOIN defaultvalues d2 ON m.color = d2.default_id
...

What i did in the end.... while it works I am still not happy. There must be something better...
SELECT m.*,
(SELECT defaultValue FROM defaultvalues WHERE default_ID = m.colour) AS myColour ,
(SELECT defaultValue FROM defaultvalues WHERE default_ID = m.size) AS mySize
FROM master m
WHERE m.master_ID = 1;

Related

How to determine the ON clause for a dynamic query using PHP?

I am trying to write a script that will allow the user to select a list of fields to be displayed from different column/table in a database. This script will need be able to generate the full query and execute it.
I am able to select the field and add the proper where clause. However, I am being challenged on how to generate the ON clause which is part of the JOIN statement.
Here is what I have done so far.
First, I defined 3 tables like so
-- list of all tables available in the database
CREATE TABLE `entity_objects` (
`object_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`object_name` varchar(60) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`object_description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`object_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- list of all tables available in the database
CREATE TABLE `entity_definitions` (
`entity_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`display_name` varchar(255) NOT NULL,
`entity_key` varchar(60) NOT NULL,
`entity_type` enum('lookup','Integer','text','datetime','date') CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
`object_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`entity_id`),
KEY `object_id` (`object_id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
-- a list of the fields that are related to each other. For example entity 12 is a foreign key to entity 11.
CREATE TABLE `entity_relations` (
`relation_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`entity_a` int(11) unsigned NOT NULL,
`entity_b` int(11) unsigned NOT NULL,
`relation_type` enum('1:1','1:N') NOT NULL DEFAULT '1:1',
PRIMARY KEY (`relation_id`),
UNIQUE KEY `entity_a` (`entity_a`,`entity_b`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
To get a list of the relations that are available, I run this query
SELECT
CONCAT(oa.object_name, '.', ta.entity_key) AS entityA
, CONCAT(ob.object_name, '.', tb.entity_key) AS entityB
FROM entity_relations as r
INNER JOIN entity_definitions AS ta ON ta.entity_id = r.entity_a
INNER JOIN entity_definitions AS tb ON tb.entity_id = r.entity_b
INNER JOIN entity_objects AS oa ON oa.object_id = ta.object_id
INNER JOIN entity_objects AS ob ON ob.object_id = tb.object_id
I am having hard time trying to figure out how to generated the JOIN statement of the query. I am able to generate the SELECT ..... and the WHERE... but need help trying to generate the ON.... part of the query.
My final query should look something like this
SELECT
accounts.account_name
, accounts.industry_id
, accounts.primary_number_id
, accounts.person_id
, industries.industry_id
, industries.name
, contact_personal.first_name
, contact_personal.person_id
, account_phone_number.number_id
FROM accounts
LEFT JOIN industries ON industries.industry_id = accounts.industry_id
LEFT JOIN contact_personal ON contact_personal.person_id = accounts.person_id
LEFT JOIN account_phone_number ON account_phone_number.number_id = accounts.primary_number_id
WHERE industries.name = 'Marketing'
I created a SQL Fiddle with my MySQL code.
How can I define the ON clause of the join statement correctly?
It is completely unnecessary to create these tables, mysql can handle all of this for you so long as you are using the InnoDB storage engine by using foreign keys.
list all tables on current database
SHOW TABLES;
get list of columns on a given table
SELECT
*
FROM
information_schema.COLUMNS
WHERE
TABLE_SCHEMA = :schema
AND TABLE_NAME = :table;
get list of relationships between tables
SELECT
*
FROM
information_schema.TABLE_CONSTRAINTS tc
INNER JOIN
information_schema.INNODB_SYS_FOREIGN isf ON
isf.ID = concat(tc.CONSTRAINT_SCHEMA, '/', tc.CONSTRAINT_NAME)
INNER JOIN
information_schema.INNODB_SYS_FOREIGN_COLS isfc ON
isfc.ID = isf.ID
WHERE
tc.CONSTRAINT_SCHEMA = :schema
AND tc.TABLE_NAME = :table;

How to Join SQL Table Content having 2 primary keys?

I have two SQL Tables in my database
Structure of table1 is ie customer_classification is
CREATE TABLE IF NOT EXISTS `customer_classification` (
`sid` int(5) NOT NULL,
`customer_id` varchar(15) NOT NULL,
`classification` varchar(5) NOT NULL,
`appendix_id` int(5) NOT NULL,
`bill_date` date NOT NULL );
Structure of table2 is ie customer_consumption is
CREATE TABLE IF NOT EXISTS `customer_consumption`
`sid` int(5) NOT NULL,
`customer_id` varchar(25) NOT NULL,
`bill_date` date NOT NULL,
`reading` float NOT NULL,
`consumption` float NOT NULL,
`energy_bill` float NOT NULL,
`meter_rent` float NOT NULL,
`arrear` float NOT NULL );
In both tables, primary keys are customer_id and bill_date, because in a particular month there is only bill corresponding to single customer.
Now, my problem is, I am not able to merge these tables data into one to display the whole record.
I have tried this Sql Query, have a look
select co.customer_id, co.reading, co.consumption, cl.classification
from customer_consumption as co
INNER JOIN customer_classification as cl
on cl.customer_id = co.customer_id
and month(cl.bill_date) = month(co.bill_date)
where month(co.bill_date) = month(now())
It is not giving me the accurate result
I am going to guess that the consumption table has records for each month and the classification record only has records when the classification changes. If so, you want to get the most recent classification. And you can do that as:
select co.customer_id, co.reading, co.consumption,
(select cl.classification
from customer_classification as cl
where cl.customer_id = co.customer_id and
cl.bill_date <= co.bill_date
order by cl.bill_date desc
limit 1
) as classification
from customer_consumption co
where month(co.bill_date) = month(now());
Try this SQL query
select co.customer_id, sum(co.reading), sum(co.consumption), cl.classification
from customer_consumption as co
INNER JOIN customer_classification as cl
on cl.customer_id = co.customer_id
and month(cl.bill_date) = month(co.bill_date)
where month(co.bill_date) = month(now())
group by co.customer_id

SQL - After receiving rows of the same data from a SELECT INNER JOIN with a WHERE...How do I take one time what is different / unique

I can use LIMIT to surrender myself to one row but I would like to learn how I can provide one of each rows rather than the several of the same rows / data
Goto : http://inks-etc.com/Script/SQL/loginform.php
Username: jason
Password: 123
Sounds like you have this setup:
create table `some_table` (
`uniq_id` bigint(20) unsigned not null auto_incremenet,
`some_data` varchar(200) not null,
`some_other_data` varchar(100) not null,
PRIMARY KEY (`uniq_id`)
) ENGINE=MyISAM AUTO_INCREMENT=260285 DEFAULT CHARSET=utf8;
create table `some_other_table` (
`other_id` bigint(20) unsigned not null auto_incremenet,
`link_to_uniq_id` bigint(20) unsigned not null,
`multiple_entry_data` varchar(100) not null,
PRIMARY KEY (`uniq_id`)
) ENGINE=MyISAM AUTO_INCREMENT=260285 DEFAULT CHARSET=utf8;
Where some_other_table can match some_table multiple times. It also sounds like you are trying something like this, and wanting one row per uniq_id:
select * from some_table
inner join some_other_table
on some_table.uniq_id = some_other_table.link_to_uniq_id
The way that you can modify this type of query to get only one entry per uniq_id is something like this, using the group by directive:
select * from some_table
inner join some_other_table
on some_table.uniq_id = some_other_table.link_to_uniq_id
group by some_table.uniq_id
Hopefully I understood your question, and hopefully this answers it.

PHP/MySQL Search code and logic for relational database schema

I have created this database schema and with help from several users on here, I have a database which takes user submitted business entries stored in the business table, which are additionally grouped under one or several of about 10 catagories from the catagories table, in the tbl_works_catagories table by matching the bus_id to the catagory id.
For example, bus_id 21 could be associated with catagory_id 1, 2, 5, 7, 8.
CREATE TABLE `business` (
`bus_id` INT NOT NULL AUTO_INCREMENT,
`bus_name` VARCHAR(50) NOT NULL,
`bus_dscpn` TEXT NOT NULL,
`bus_url` VARCHAR(255) NOT NULL,
PRIMARY KEY (`bus_id`)
)
CREATE TABLE `categories` (
`category_id` INT NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(20) NOT NULL,
PRIMARY KEY (`category_id`)
)
CREATE TABLE `tbl_works_categories` (
`bus_id` INT NOT NULL,
`category_id` INT NOT NULL
)
Now, what i want to do next is a search function which will return businesses based on the catagory. For example, say one of the businesses entered into the business table is a bakers and when it was entered, it was catagorised under Food (catagory_id 1) and take-away (catagory_id 2).
So a visitor searches for businesses listed under the Food catagory, and is returned our friendly neighbourhood baker.
As with all PHP/MySQL, i just can't (initially anyway) get my head around the logic, never mind the code!
You should setup foreign keys in your tables to link them together.
CREATE TABLE `business` (
`bus_id` INT NOT NULL AUTO_INCREMENT,
`bus_name` VARCHAR(50) NOT NULL,
`bus_dscpn` TEXT NOT NULL,
`bus_url` VARCHAR(255) NOT NULL,
PRIMARY KEY (`bus_id`)
)
CREATE TABLE `categories` (
`category_id` INT NOT NULL AUTO_INCREMENT,
`category_name` VARCHAR(20) NOT NULL,
PRIMARY KEY (`category_id`)
)
CREATE TABLE `tbl_works_categories` (
`bus_id` INT NOT NULL,
`category_id` INT NOT NULL,
FOREIGN KEY (`bus_id`) REFERENCES business(`bus_id`),
FOREIGN KEY (`category_id`) REFERENCES categories(`category_id`)
)
Then your search query would be something like:
SELECT b.*
FROM business b, categories c, tbl_works_categories t
WHERE
b.bus_id = t.bus_id AND
c.category_id = t.category_id AND
c.category_id = *SOME SEARCH VALUE*
which using JOIN would be written as:
SELECT b.*
FROM business b
JOIN tbl_works_categories t
ON b.bus_id = t.bus_id
JOIN categories c
ON c.category_id = t.category_id
WHERE c.category_id = *SOME SEARCH VALUE*
Maybe you want something like this:
SELECT `bus_id` FROM `tbl_works_categories` WHERE `category_id` = *some id from the search*
AND `category_id` = *some other id from the search*;
Although you'd need those ids- there are a few ways to do this, I'll describe probably the most straight forward...
You get categories from $_POST, so let's just say you have 2 of them entered. (Food, and take-away). Parse these however you want, there are multiple ways, but the point is they're coming from $_POST.
execute this sort of thing for each one you find:
SELECT `category_id` FROM `categories` WHERE `category_name` LIKE '%*the name from $_POST*%';
Store these results in an array...based on how many you have there you can build an applicable query similar to the one I describe first. (Keep in mind you don't need and AND there, that's something you have to detect if you return > 1 category_id from the second query here)
I'm not going over things like security..always be careful when executing queries that contain user submitted data.
An alternate solution might involve a join, not too sure what that'd look like off the top of my head.
Good luck.
If you want all businesses that are related to the given category-id, your SQL-statement would look something like this:
SELECT `business`.`bus_name`
FROM `business`
WHERE `business`.`bus_id` = `tbl_works_categories`.`bus_id`
AND `categories`.`category_id` = `tbl_works_categories`.`category_id`
AND `categories`.`category_id` = 1;
Where 1 in this case is your food-category, but could be your PHP variable where the ID of the category the user selected is stored.
And one hint: Be sure to name your tables either in plurar or in singular. You are mixing both and could get confused.

how to connect two tables with sql and php

I am a bit new to sql and php so I need some help here. I created two tables and I want to establish a 'one-to-many relationship' but I can't figure out how I can give the data through the php file. Here is some code:
CREATE TABLE `details` (
`details_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL,
`latitude` double NOT NULL,
`longitude` double NOT NULL,
`mytext` varchar(60) NOT NULL,
`description` varchar(600) NOT NULL,
`city_details` int(11) NOT NULL,
PRIMARY KEY (`details_id`),
FOREIGN KEY (`city_details`) REFERENCES city(`city_id`)
on update cascade
);
CREATE TABLE `city` (
`city_id` int(11) NOT NULL AUTO_INCREMENT,
`cityName` varchar(30) NOT NULL,
PRIMARY KEY (`city_id`)
);
So I want to write a cityName and then be able to give some data for various places of the city. How can I create a php file so that I will only have to give the name of the city (to table city) and then write things for multiple locations inside the city (to table details).
$sql="SELECT * FROM `details` as d INNER JOIN `city` as c ON d.city_details=c.city_id;";
if you want to look for a city name you can use this
$sql="SELECT * FROM `details` as d INNER JOIN `city` as c ON d.city_details=c.city_id WHERE c.cityName='The name you're looking for'";
then to fetch everyting from the table use this code
while($row=mysql_fetch_assoc(mysql_query($sql))){
echo $row['name']; //for name
echo $row['mytext']; //etc.
}
for more info see
http://dev.mysql.com/doc/refman/5.1/en/join.html
and
http://php.net/manual/en/function.mysql-fetch-assoc.php

Categories