I need a query to retrieve all shops that are related to specifif "industry"
My mate designed table without foreign key and as many to many relation, he used Regex when separating with ","
TABLE shops
id | phone | address | type
1 | 11111 | XXXXX | ,10,12,13
3 | 22121 | XXXXX | ,33,37,38
5 | 11111 | XXXXX | ,51,52,55
TABLE types
ID | industry | type
10 | service | taxi
12 | service | delivery
13 | service | mail
33 | primary | electriticy
37 | primary | water
38 | primary | gas
51 | edu | primary school
52 | edu | high school
55 | edu | university
60...
70...
Is there any possibility to retrieve like ex: with WHERE types.industry = 'service' in a single query?
I'm having trouble to do it, though all about Joins or Subqueries etc, but i came up with no solution.
Looking for help.
Thanks in advance
Assuming I'm understanding correctly, one option is to join using find_in_set():
select *
from shops s
join types t on find_in_set(t.id, s.type)
where t.industry = 'service'
SQL Fiddle Demo
Related
I have a small database:
+-----------+-----------+------------------------+
| Name | Number | Hobby |
+-----------+-----------+------------------------+
| Alex | 2, 3 | Game, Shopping |
+-----------+------------------------------------+
It's mean Number 2 is Game and Number 3 is Shopping.
How can I show above data like this table
+-----------+-----------+
| 2 | Game |
+-----------+-----------+
| 3 | Shopping |
+-----------+------------
Your database is not normalized. You need a third table that will be what's usually called a join table.
The people table. The primary key is id
+-----------+-----------+
| Id | Name |
+-----------+-----------+
| 1 | Alex |
| 2 | Thor |
| 3 | Iron Man |
| 4 | Dr Stange |
| 5 | Thanos |
+-----------+------------
The hobbies Table
+-----------+-----------+
| Id | Name |
+-----------+-----------+
| 1 | Game |
| 2 | Shopping |
| 3 | Fighting |
+-----------+-----------+
Join table called (for example) people_hobbies
+-----------+-----------+
| person_id | hobby_id |
+-----------+-----------+
| 1 | 1 |
| 1 | 2 |
+-----------+-----------+
This people_hobbies table will use person_id and hobby_id to create a multi field primary key. This will ensure that you will not be able to add the same combination twice... which should not even make sense.
person_id is a foreign key that references the id from the people table.
hobby_id is a foreign key that references the id from the hobbies table.
Having foreign keys will let you avoid having a key in the people_hobbies table that do not exist in both the people and the hobbies table.
The example in the table below shows that the person id 1 has two hobbies (1 and 2). For a human, that translates to Alex's hobbies are Game and Shopping.
The above structure will let you manage your DB the way most people do.
Just keep a few things in mind:
You cannot add anything in people_hobbies before they exist in both people and hobbies tables
You must have the CASCADE UPDATE and CASCADE DELETE to the foreign key definitions so that when you delete a person or a hobby from your tables, it will remove the relationship from the people_hobbies table.
SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+
SELECT * FROM bad_schema;
+------+--------+----------------+
| name | number | hobby |
+------+--------+----------------+
| Alex | 2, 3 | Game, Shopping |
+------+--------+----------------+
CREATE TABLE better_schema AS
SELECT DISTINCT name
, SUBSTRING_INDEX(SUBSTRING_INDEX(number,',',i+1),',',-1) + 0 number
, TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(hobby,',',i+1),',',-1)) hobby
FROM bad_schema
, ints;
SELECT * FROM better_schema;
+------+--------+----------+
| name | number | hobby |
+------+--------+----------+
| Alex | 2 | Game |
| Alex | 3 | Shopping |
+------+--------+----------+
I want to create a little blog system. Under each article should be a comment function. I think, I need 2 Databases (1x for the normal articles, 1x for the comments of ech article). Now I dont now how i can create a relationship between boths databases. Here is a picture:
On this picture are the attributes of each database. And how can i contact the databases then? (write & read)
make for every type you want a table. i.e one for articles, writers, categorys etc.
Table articles
+----+-----------+-------+------------+---------+-------------+
| id | writer_id | title | date | message | category_id |
+----+-----------+-------+------------+---------+-------------+
| 1 | 12 | foo | 2015-01-26 | text | 34 |
| 2 | 12 | bar | 2015-01-27 | bar | 32 |
+----+-----------+-------+------------+---------+-------------+
table writer and so on
+-----------+------+
| writer_id | name |
+-----------+------+
| 12 | test |
+-----------+------+
Table comments
+------------+------------+---------+------+
| comment_id | article_id | comment | date |
+------------+------------+---------+------+
and so on
afterwards you can connect them in your sql
SELECT
`articles`.`title`,
`writer`.`name`,
`comments`.`comment`
FROM
`articles`
LEFT JOIN `writer` ON (`writer`.`writer_id` = `articles`.`writer_id`)
LEFT JOIN `comments` ON (`comments`.`article_id` = `articles`.`id`)
Have a look at http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins for a visual explanation of joins.
You need two tables in the same database and you can connect them with a foreign key.
ARTICLE (ID_ARTICLE,WRITER,TITLE,DATE,MESSAGE....)
COMMENT (ID_COMMENT,FK_ARTICLE(to know the article), COMMENT_WRITER ... )
I want to know if i'm setting up this database schema the most effective way.
I am trying to output snowboarding terminology and what it means for each product on my website. The tables that I have set up for this:
products
+----+--------+--------+-------------+
| id | brand | name | product_type|
+----+--------+--------+-------------+
|8000| burton | diode | binding |
+----+--------+--------+-------------+
terminology_products
+----+--------+------------+
| id | att_id | product_id |
+----+--------+------------+
| 1 | 51 | 8000 |
| 2 | 52 | 8000 |
+----+--------+------------+
terminology
+--------+-----------+--------+---------------------+
| att_id | type | key | value |
+--------+-----------+--------+---------------------+
| 52 | baseplate | EST | details about EST |
| 53 | baseplate | Hinge | details about Hinge |
+--------+-----------+--------+---------------------+
Then I query
SELECT products.ProductName, products.Brand, terminology.type, terminology.key, terminology.value
FROM products
JOIN terminology_products
ON terminology_products.product_id = products.ID
JOIN terminology
ON terminology_products.att_id = terminology.att_id
WHERE products.id = 8000
And get the results that I am looking for, but I feel like this could be an over complicated way of doing it. Is there a simpler way? Thank you for any insight or help.
Yes, it is a correct way. It's common solution.
Your "terminology_products" table contains foreign keys, and it allows you to make "many to many" relation between tables.
I have a closed-source software written in C#/.NET from a VoIP company which is impossible to customize and wanted to create custom front-end using PHP. I gained access to the database and now see how it functions. I wanted to output the user his 'speed dial' numbers, but having issue solving it. Here are the tables structures:
'customer' table
+-------------------------------------------------------------------------+
| CustomerID | FirstName | LastName | Balance | Email | Password | Status |
|-------------------------------------------------------------------------|
| 1 | Homer | Simpson | 5.00 | h#s.s | iheartm | 1 |
| 2 | Marge | Simpson | 3.00 | m#s.s | ihearth | 1 |
+-------------------------------------------------------------------------+
'calls' table
+------------------------------------------------------------------------+
| CallID | Caller | Callee | ServiceID | Duration | Cost | CustomerID |
|------------------------------------------------------------------------|
| 1 | 1234567 | 7654321 | 30 | 60 | 1.00 | 1 |
| 2 | 7654321 | 1234567 | 45 | 120 | 2.00 | 2 |
+------------------------------------------------------------------------+
'ani' (speed-dial) table
+---------------------------------------+
| PhoneNumber | ServiceID | ContactName |
|---------------------------------------|
| 1234567 | 45 | Homer |
| 7654321 | 30 | Marge |
+---------------------------------------+
As you can see, 1234567 is Homer's phone number and in Marge's speed dial list and 7654321 is Marge's number in Homer's list. Just like I can pull up customer's balance when logged in using: $current_user['Balance'];, is there way to show user his 'speed dial' numbers in PHP?
This request doesn't achieve what you want ?
SELECT
a.CustomerID, a.FirstName, a.LastName, a.Balance, a.Email, a.Status,
b.ServiceID,
(SELECT GROUP_CONCAT(CONCAT(ContactName,':',PhoneNumber)) FROM ani GROUP BY PhoneNumber WHERE ServiceID = b.ServiceID)
FROM customer a
LEFT JOIN calls b ON a.CustomerID = b.CustomerID
WHERE a.CustomerID = 'replace_by_customer_id'
This should fetch the data of the customer table, plus a string that results from concatenating the speed-dial numbers of the customer connected.
I assume that a customerid corresponds to one unique serviceid found in calls, and the serviceid in the table ani indicates the owner of the speed-dial number. But it seems a weird architecture, so you should give us more data or informations about the tables...
There seems to be a missing relation from ServiceID to a specific entry in customer. It would seem strange that the calls table would provide that relation, it should merely use it.
With only the information you supplied you can only join calls to link the CustomerID with the ServiceID which I suppose you have. The query would look like this:
SELECT ContactName, PhoneNumber FROM ani
LEFT JOIN calls ON ani.ServiceID=calls.ServiceID
WHERE calls.CustomerID=xxx
I have 14 tables (one for every year) with product code, firm name and invoice numbers. Main structure of table is identical (product code, ID), but there can be some variables in names of firms.
Table2011
| ID | productcode | firm1 | firm2 | firm3 | etc |
| 1 | G-00001 | 2;5;40| 32;67 | | 150 |
| 2 | G-00005 | | 50 | | |
|etc | | | | | |
Table2010
| ID | productcode | firm1 | firm2 | firm3 |etc |
| 1 | G-00001 | 1;10 | | 55 | |
| 2 | G-00003 | | 2 | | |
| 3 | G-00005 | | 50 | 40 | |
| etc| | | | | |
Table2009
...
Column Firm1 do not usually equals to same firm as firm 1 in other table
I am using table editor to work with tables (adding columns to table, editing values…).
I would like to know if it is possible to achieve result like below. It is above my PHP skills.
Product G-00001 page
…
<UL>
<LI>Year 2011: 150etc; 67firm2; 40firm1; 32firm2; 5firm1; 2firm1</LI>
<LI>Year 2010: 55firm3; 10firm1; 1firm1</LI>
<LI>Year 2009: ...</LI>
...
</UL>
…
Lemme begin with book recommendation : SQL Antipatterns. You will need it, doesn't matter if you caused this mess or ar just assigned to fix it.
If i was in your place, first thing would do would be to fix the database structure. This is madness. You do not need a new table for each year and new column for each company. Database is not a form of Excel spreadsheet.
Invoices Years Companies
----------------- ------------- ---------------
| product_code PK | | year_id PK | | company_id PK |
| company_id FK | | number | | title |
| amount | ------------- ---------------
| year_id FK |
-----------------
Where PK - primary key and FK - foreign key.
This structure would make the gathering of information much much much MUCH easier.
If you just want to display the data and not worry about the restructuring just yet you can use a JOIN to display the information from all the tables.
Although I would agree with teresko you really need to redesign that database. It is not maintainable the way it is.