Multitable stores when other store locations are in sub-table - mysql

I have a database that allows a list of businesses.
The Master table has the customer aka businesses details:
id
firstname
lastname
tradingname
storeaddress
state
postcode
In a table called Otherstores, I have the following:
master_id
store_id
storeaddress
state
postcode
phonenumber
What I now need to do is a PHP script that allows me to show all the stores in a list function but here is the catch:
I only want to show 8 stores from different types of categories so they are random.
However I then need it NOT to show a store twice on the same search.
I need it to make the sub-stores aka Otherstores also be randomly added into the query so that they are seeable as well.
I wondering the best way to do this.
WHY I DON'T HAVE ANY CODE:
It's tough to show you code as my idea was to do a left join or INNER join and limit it to id 1.
However I know that won't work because I would need to be able to join them together some how, but I want each sub store to be like its a master store so if I join it to the master table I can't see that working, and instead you will just get errors.

Related

MySql multiple selects in a single query

I have a restful web service that has an endpoint for getting all sub-resources of a single resource (say, for a contrived example, selecting all pets for a certain pet store by making a GET request to http://www.url.com/stores/1234/pets).
This web service is highly concurrent, and gets hit with many requests at once. I'd like to write a single query (for a MySQL database) that allows me to retrieve the number of pets associated with a store, and to be able to distinguish if a store with that id doesn't exist.
That is, if a store with that id exists, but there are no pets from that store, it should return one thing (an empty list); but if that store id does not exist, then raise an exception. Can someone please help me write this SQL query?
Here is some pseudo-sql
CREATE TABLE STORE(
STORE_ID <- AUTO GENERATED PK
.....
)
CREATE TABLE PET(
PET_ID <- AUTO GENERATED PK
STORE_ID <-FOREIGN KEY POINTING TO STORE TABLE
)
STORE|PET
1 | 1,2
2 | NO PETS
I would want the query to be able to give different outputs for querying for store id 2 (where the store exists, but no pets associated with it) and querying for pets for store 3 (where no store with id 3 exists).
Please avoid multiple queries (even using locks/transactions) or stored procedures if possible.
Additional notes:
For the web service, at first I had made a query to check that a store exists with that id, if it doesn't, then throw an exception (that turns into a 404). However, in a highly concurrent application, we could check that the store exists, and find that it does. However, there could be another request that deletes that store before our next query (to retrieve all pets) occurs. In this case, I would like to be true to RESTful principles and return a 404, rather than an empty list. Hence, I would need to distinguish between the two cases. I know how to do this with a transaction and a lock (select for update), but I'd prefer to do this another way if possible.
select s.store_id, count(p.store_id)
from store as s
left join pet as p -- get a row if the store has no row in PETS
on s.store_id = p.store_id
where s.store_id = 9
group by s.store_id -- get no row even if store doesn't exist.
The LEFT join assures that the store is returned even if it has no rows in PETS, the count(p.store_id) returns 0 (caution: don't use count(s.store_id), this would result in 1).
And the GROUP BY utilizes the fact that a COUNT with Group By returns no result if there's no input row (caution: without Group By the Count will return a row).

Displaying Results if a Condition Matches a Name

There is a table in our database that contains customer information including their first and last name. The first and last name are stored as separate fields and not together as one name. There is also a table which stores a referral field. In this field, someone can place the name of the customer that referred them to our services.
I would like to utilize a query that will take the referral field (which would contain the name of a prior customer) and match it up to the record to that prior customer.
I thought the below would work:
SELECT APPLICATION_ID
FROM APPLICATION_TABLE
JOIN APPU_USER ON APPU_APPLICATION_ID = APPLICATION_ID
LEFT JOIN APBD_APP_BASIC_DATA ON APBD_APPLICATION_ID = APPLICATION_ID
WHERE CONCAT(APPU_FIRST_NAME,' ',APPU_LAST_NAME) = APBD_REFERRAL_STRING;
What do I need to utilize to be able to do this?
everything looks fine in your query. Is a good practice to put the table names when you use two or more tables in a query to avoid same fields conflicts, something like:
LEFT JOIN APBD_APP_BASIC_DATA ON APBD_APP_BASIC_DATA.APBD_APPLICATION_ID = APPLICATION_TABLE.APPLICATION_ID
also, take in mind than
CONCAT(APPU_FIRST_NAME,' ',APPU_LAST_NAME) = APBD_REFERRAL_STRING;
can cause problems if referral string is in format last name,first name or first name, last name, or with 2 spaces

mysql join table1 to last entry of table2

I have a simple mysql query that get customer's equipment detail (general info like id, name, job site):
SELECT *
FROM equipments
WHERE CUSTOMER_ID = 87
But each equipment has is own table of variable datas like fuel level, engine hours, latitude, longitude (the equipment ID is the name of the table). So now, I'm making a query that takes all the general info and put it into an array. After that, I create a loop that include a query for each equipment who looks into the right table (table name = equipement ID) and get the last entry.
I tested it with 4 equipments and it takes on average 4 seconds to load the page which is a bit too long. Is there a way to make it shorter and put this inside one query?
Can I join the first table with the last entry of the second table? The second table is changing and named like the equipment id of the first table.
I found this post, but I can't make it work for this application because I can't set the ON statement.
https://stackoverflow.com/a/3619209/1895428

'Likes' system database

I am developing web application where I have to implement 'Likes' system as facebook has. Application will have a few categories of products that customer can 'like'. So I have started to create database, but I stuck on one obstacle. As I understand there are two ways of doing this:
First. Create one database table with fields of "id, user_id, item_category, item_id". When user click 'like' button information will be saved in this table with various categories of products (item_category).
Second. Create several tables for certain categories of item. For instance, "tbl_item_category_1, tbl_item_category_2, tbl_item_category_3" with fields of "user_id, item_id".
Would be great to get more insight about best practices of this kind database structures. Which works faster? and more logical/practical? I will use only several categories of items.
I would go with the first version with a table structure similar to this:
User Table: PK id
id
username
Category Table: PK id
id
categoryname
Like Table: PK both user_id and catgory_id
user_id
category_id
Here is a SQL Fiddle with demo of table structure with two sample queries to give the Total Likes by user and Total Likes by category
The second one - creating multiple tables is a terrible idea. If you have 50-100 categories trying to query those tables would be horrible. It would become completely unmanageable.
If you have multiple tables trying to get a the total likes would be:
Select count(*)
from category_1
JOIN category_2
ON userid = userid
join category_3
ON userid = userid
join .....
Use one table, no question.
The first method is the correct one. Never make multiple tables for item categories, it makes maintaining your code a nightmare, and makes queries ugly.
In fact, the general rule is that anything that is dynamic (i.e. it changes) should not be stored as a set of static objects (e.g. tables). If you think you might add a new type of 'something' later on, then you need a 'something' types table.
For example, imagine trying to get a count of how many items a user has liked. With the first method, you can just do SELECT COUNT(*) FROM likes WHERE user_id = 123, but in the second method you'd need to do a JOIN or UNION, which is bad for performance and bad for maintainability.
The first method is the correct one. Because you dont know how many categories you will be having and it is very difficult to get the data.

What is the best way to count rows in a mySQL complex table

I have a table with the following fields (for example);
id, reference, customerId.
Now, I often want to log an enquiry for a customer.. BUT, in some cases, I need to filter the enquiry based on the customers country... which is in the customer table..
id, Name, Country..for example
At the moment, my application shows 15 enquiries per page and I am SELECTing all enquiries, and for each one, checking the country field in customerTable based on the customerId to filter the country. I would also count the number of enquiries this way to find out the total number of enquiries and be able to display the page (Page 1 of 4).
As the database is growing, I am starting to notice a bit of lag, and I think my methodology is a bit flawed!
My first guess at how this should be done, is I can add the country to the enquiryTable. Problem solved, but does anyone else have a suggestion as to how this might be done? Because I don't like the idea of having to update each enquiry every time the country of a contact is changed.
Thanks in advance!
It looks to me like this data should be spread over 3 tables
customers
enquiries
countries
Then by using joins you can bring out the customer and country data and filter by either. Something like.....
SELECT
enquiries.enquiryid,
enquiries.enquiredetails,
customers.customerid,
customers.reference,
customers.countryid,
countries.name AS countryname
FROM
enquiries
INNER JOIN customers ON enquiries.customerid = customers.customerid
INNER JOIN countries ON customers.countryid = countries.countryid
WHERE countries.name='United Kingdom'
You should definitely be only touching the database once to do this.
Depending on how you are accessing your data you may be able to get a row count without issuing a second COUNT(*) query. You havent mentioned what programming language or data access strategy you have so difficult to be more helpful with the count. If you have no easy way of determining row count from within the data access layer of your code then you could use a stored procedure with an output parameter to give you the row count without making two round trips to the database. It all depends on your architecture, data access strategy and how close you are to your database.