Ok, so I am creating a sort of online shopping service and I have a DB that requires a field to match up against multiple other fields. They need to be stored, so that they can be ignored and set as maybe for later viewing. I know that setting up a comma delimited field is usually unwise, but I cannot figure out a better way to keep track of the matches while being able to categorize them into separate columns later on.
For eg, I have 25 products to sell and have 10 cities in which I want to sell them. Some can be shipped to 5 cites and some can be shipped to 9 cities. Now if someone searches for products in one particular city, how will only those products appear as a search result that are available for sale in that city only?
Does anyone have any better way of doing this without the comma delimited field?
I'd use about 3-4 tables:
products - having data of each product
cities - having data of relevant cities
product_cities - having relation between product and city
If a product can be shipped to 5 cities, it would have 5 rows in product_cities containing the same product_id and different city_id.
When a person searches, have something like:
SELECT pr.*
FROM cities AS c
INNER JOIN product_cities AS pc
ON c.id = pc.city_id
INNER JOIN products AS pr
ON pc.product_id = pr.id
WHERE c.name LIKE 'New York'
Two way to you will be match one column value with mutiple value using 'case statement' or in statement in where clause like:
select (case when col1>col2 then col2 else
when col1>col4 then col4 else
col1 end) as colname, col5 from tablename
or
select * form tablename where col11 in (1,2,3)
Make three different tables - one for the products you have, one for the cities you want to sell them in and one for describing where each product can be send (id, product_id, city_id).
From there, just use simple joins to select only the possible products for the selected city.
use a n:n Table:
Products Table
products
id | name
city table
cities
id | name
Mapping (unique constraint over BOTH columns, not single constraints):
shipping_information
product_id | city_id
Then you can easily select all available cities for a product, or select all products, which are shipped to a certain city.
All available cities for product 4: SELECT * FROM cities, shipping_info WHERE cities.id = shipping_info.city_id AND shipping_info.product_id = 4
All available products for city 3: SELECT * FROM products,shipping_info WHERE shipping_info.id = 3 AND shipping_info.product_id = products.id
Related
Table-1 parts is a full parts catalog. Primary index field is PartID (int, auto-increment).
Table-2 inventory is a list of partIDs connected to various distributors. Important fields are DistID and PartID. Primary index field is InvID (int, auto-increment).
In Table-2, there will be a unique entry (InvID) for each part a distributor has, so many duplicate DistID/PartID entries.
Given a particular DistID, I must first get a list of all PartIDs associated with that DistID (inventory Table-2), and then SELECT * FROM parts (Table-1) for all those PartIDs.
The end result set is a list of all part information (T1) for each unique part held by a distributor (T2).
I'd like to do this using a single mysql query.
What you want is to start with a distinct list of the inventory for that distributor. This is our base query (replace the question mark with your actual distributor ID):
SELECT DISTINCT partID FROM inventory WHERE DistID = ?
Then we modify that query to join on the parts table to pull back the part information:
SELECT DISTINCT i.partID, p.* FROM inventory i INNER JOIN parts p ON i.partID = p.partID WHERE i.DistID = ?
thats not a PHP question at all.
Anyway, if I understood your question your should try this:
SELECT parts.* FROM parts WHERE parts.PartID IN (SELECT invetory.PartID FROM invetory WHERE invetory.DistID = 'wanted_DistID');
You should change 'wanted_DistID' for you wanted DistID.
Hope I could help.
I'm working on a PHP application for University which pretends I buy and resell a specific item to/from countries.
I have a table which contains transaction IDs and the names of the countries that made them.
I've been trying to count up the number of times a specific country's name appears in the database table then print out a table on the webpage showing each countries name and the number of times they appear in the table like below, but I can't find any examples of this kind of thing anywhere, they're always too different to be of much help. I would also like to order the table by max to min count and also be able to limit the number of countries shown using radio buttons (which I've already got working).
countryName | numberOfSales
Belize | 10
Brazil | 6
Cameroon | 64
Colombia | 23
Costa Rica | 47
You need to select the country and count, then group by the country. If you want to order it you need to add that on as well.
SELECT
countryName,
count(*) as numberOfSales
FROM
sales
GROUP BY
countryName
ORDER BY
numberOfSales DESC
This query will have 2 columns in the results. The country names and the number of times they appear according to the grouping. We are grouping all of the records by the country name column. In the query, we name the column numberOfSales, so we can use that when ordering it so that the countries will be in order from max to min in numberOfSales.
If you have two tables in your database (MySql in my case), one where you store the different countries and one for the sales/orders.
Table countries:
id INT
country VARHCAR(255)
Table: sales:
id INT
country_id INT
title VARCHAR(255)
Here there is a 1:many relationship between the two tables. One country can have many sales, but a sale can only belong to one country.
You can then fetch the number of sales for specific country by running the following SQL query.
If you want to find the number of sales for Denmark you could do:
SELECT countries.country, COUNT(*) AS numberOfSales
FROM countries
JOIN sales
ON sales.country_id = countries.id
WHERE countries.country = 'denmark';
If you want to see the total number of sales for each country you can use the following SQL query:
SELECT countries.country, COUNT(*) AS numberOfSales
FROM countries
JOIN sales
ON sales.country_id = countries.id
GROUP BY countries.country;
Here the GROUP BY clause will fetch the result for each of the countries in your countries table. You can add LIMIT clause if necessary.
I hope this doesn't complicate things too much. You will thank me later by using two tables (I do not know if you already do. If you do, NICE).
Related to counting identical rows in MySql: Count number of identical rows in MySQL with PHP
Best regards.
I have searched around for an issue like I have but I have not found anything :-( , so, I have decided to open a question. I'm working on a travel agency website and I'm stuck. I have 6 tables:
1. category
2. country
3. city
4. type
5. offer
6. price
Now, the relations of each one is like this: in offer table are recorded id's of category, country, city, type and, in price table is recorded offer id. In this way, via admin panel, the process starts by creating a new offer and after that, creating prices for that offer. This is way the offer id is recorded in price table and not inverse.
What I have right now is the following:
SELECT DISTINCT
price.prFood,
offer.*
FROM
category,
country,
city,
`type`,
price
INNER JOIN offer
ON price.prOfferID = offer.offerID
WHERE offerType = typeID
AND categoryID = offerCategory
AND countryID = offerCountry
AND prOfferID = offerID
AND offerActive = '1'
AND offerCity = cityID ;
This query shows correctly, only once, every offer that has a price but, what I need is to show also offers that are active and don't have a price. So, I need a little help on the correct query to show all offers that are active, have or don't have a price.
Use left join for your price table and move where condition in on clause. I have used aliases to give short names to table, so if I have not selected proper columns, please use right aliases for the columns.
SELECT DISTINCT
p.prFood,
o.*
FROM
offer o
LEFT JOIN price p ON o.offerID = p.prOfferID
INNER JOIN category ca ON o.offerCategory = ca.categoryID
INNER JOIN country c ON o.offerCountry = c.countryID
INNER JOIN city ci ON o.offerCity = ci.cityID
INNER JOIN `type` t ON o.offerType = t.typeID
AND o.offerActive = '1'
I have three tables:
Store (linked to address and category tables)
Brand (linked to category table)
Shopping mall (linked to address)
When I do a search for ac, I need to search each table and fetch all rows starting with ac.
I also need to fetch
the address and categories for each store
the address for each shopping mall
the categories for each brand
My search is using autocomplete but I don't want to display the result in one big chunck, but rather divide the result in store, brand and shopping mal.
My current solution is to execute 3 separate SQL queries, and put the result in ann array and return this.
But I don't feel doing the query this way is the most efficient way. Is there a better way to increase the speed of my search? Is there a best practice for complex search?
I am indexing things like name and address.
Currently I can only use MySQL DB.
Without knowing your exact table structure, I'd propose something similar to this:
SELECT
stores.name AS name,
addresses.street AS street,
addresses.city AS city,
'store' AS type,
GROUP_CONCAT(categories.categoryname) AS category
FROM
stores
INNER JOIN
addresses ON addresses.addressid = stores.storeid
INNER JOIN
categories AS categories.storeid = stores.storeid
WHERE
stores.name LIKE "ac%"
GROUP BY
stores.storeid
UNION
SELECT
brands.name AS name,
'-' AS street,
'-' AS city,
'brand' AS type,
GROUP_CONCAT(brandcategories.categoryname) AS category
FROM
brands
INNER JOIN
brandcategories AS brandcategories.brandid = brands.brandid
WHERE
brands.name LIKE "ac%"
GROUP BY
brands.brandsid
UNION
SELECT
malls.name AS name,
addresses.street AS street,
addresses.city AS city,
'mall' AS type,
'-' AS category
FROM
malls
INNER JOIN
addresses ON addresses.addressid = malls.mallid
WHERE
malls.name LIKE "ac%"
GROUP BY
malls.mallid
Do a SELECT... for each of the tables and UNION them. Each SELECT gets a column type, where type can be store, brand or mall. So you can distinguish it later in your PHP code.
Since every SELECT in a UNION needs the same columns, also the SELECT for e.g. brand returns an address, but it's empty.
In this example, every store/brand can have multiple categories, which get returned at once in a comma separated field (GROUP_CONCAT(categories.categoryname)).
I have 3 tables holding products for a restaurant. Products that reside in the bar, food and ingredients.
I use php and mysql. I have another table that holds information about the orders that have been made so far. There are 2 fields, the most important ones, that hold information about the id of the product and the type (from the bar, from the kitchen or from the ingredients).
I was thinking to write the sql query like below to use either the table for bar products, kitchen or ingredients but it doesn't work. Basically the second table on join must be either "bar", "produse" or "stoc".
SELECT K.nume,
COUNT(K.cantitate) as cantitate,
SUM(K.pret) as pret,
P.nume as NumeProduse
FROM `clienti_fideli` as K
JOIN if(K.tip,bar,produse) AS P ON K.produs = P.id_prod
WHERE K.masa=18 and K.nume LIKE 'livrari-la-domiciliu'
GROUP BY NumeProduse
I don't think you can do that.
can you change the database schema? a better option would be to have bar, food and ingredients in a single table (eg product) with a field type which would be either 'bar', 'produse' or 'stoc'
SELECT K.nume,
COUNT(K.cantitate) as cantitate,
SUM(K.pret) as pret,
P.nume as NumeProduse
FROM `clienti_fideli` as K
JOIN product AS P ON K.produs = P.id_prod AND P.tip = <product_type>
WHERE K.masa=18 and K.nume LIKE 'livrari-la-domiciliu'
GROUP BY NumeProduse