Simple SQL logic validation - sql

I would like to kindly ask more experience developers to give me a quick evaluation of really simple sql relation logic. I am very new on the field of databases so I don't want to make logic mistake which when found will cause me to rewrite the whole thing.
So here's the thing
I have a few products, let's say a fridge, washing machine and microwave.
To every item belong a few files: manual, quick-start guide, photos etc.
My implementation in database bases on following scheme:
1. Table 1: Product
columns here are:
name
description
2. Table 2: File
name
description
file
product (Foreign Key)
So basically I just make the connection between file and the product by giving every file a product it belongs to.
It seems a little bit counterintuitive tough yet I don't really know why.
Hence this logic is base of the whole system I wanted to ask if I didnt make some simple mistake here.
I guess that for someone experienced it will be obvious how it should be done.
Thanks in advance

Given that files and products may have a many-to-many relationship, the typical way to handle this is via the use of a junction table:
product_file (product_id, file_id)
The sole purpose of this table is to maintain relationships between products and their files. But note that none of the metadata is actually stored here. Instead, the metadata is stored in the following slightly modified file and product tables:
product (id, name, description)
file (id, name, description)
To see how this works, here is a query which finds the names of all files associated with a certain product:
SELECT
f.name
FROM file f
INNER JOIN product_file pf
ON f.id = pf.file_id
INNER JOIN product p
ON pf.product_id = p.id
WHERE
p.name = 'some product';

You might look for the following solution, or similar:
Product (ProductId, Name, Description)
CoverItem (CoverItemId, Name, Description)
File (ProductId, CoverItemId, File)
Let's say you have a fridge (ProductId=1) and a washing machine (ProductId=2).
As additional ("cover" or whatever term you like) items you define the following: manual (CoverItemId=1) and quick-start guide (CoverItemId=2).
This doesn't make any meaningful information so far, but now you should have a repository of your items you can use.
At last, you insert data to the File table, which connects a product with the cover-item. As an example, (ProductId=1, CoverItemId=1, File="D:\SomeFolder\FridgeManual.txt") would mean that there's a manual for a frigde in the path "D:\SomeFolder\FridgeManual.txt".
HTH

Related

Adding new product with category tree - specific price problems

I installed an add-on for bulk action (called ba_importer v 1.1.24), I upload an Excel file with my data and create a group of products.
I can set the categories' tree or manually add ID of main categories and associated. I tried with no luck to use the tree features (like Home/Products/etc) and so I use all the ID of main category and all the associated. The result is a product with the correct categories set, but with no specific price from the customer group linked to a category.
I tried to edit a single product, remove all categories and set it one by one (set one, save, set one, save etc.) and then the specific price from the group linked to a category appears to the product.
Is there a better solution? I'm thinking about make a personal PHP page that reads an Excel file and sets all the information about the product, but I'm scared to face the same problem with the specific price. 
There is no such thing as "category-related specific price",
if you have specific prices tied to customer groups , these are created as a result of the add/update product action with ps_specific_price DB entries having id_group with your restricted ID.
It is likely that the bulk module acts directly with DB queries to speed up things and bypasses this operation, I've seen this behaviour with those kind of modules in the past.
Since you are talking of a paid add-on, I would definitely seek help from the developer.

Oracle Application Express SQL Query to show meaningful information

I am trying to write a query that 1) works and 2) shows meaningful information.
However, I can't seem to complete both scenarios. Both bits of code do work to a degree. My SQL query does work by showing all the useful information a user wants but when you click the edit button it doesn't link properly so it won't allow the user to update that row. The other shows only keys and rowid but when you click edit does show the information and allows it to be updated.
So as not to get another down-voted question, I have taken pictures of each scenario to show the problem, but, ultimately, I need to show meaningful information: an id or key isn't meaningful to the vast majority of users.
Here is my code
SELECT APPLICATIONS.APP_ID, APPLICATIONS.SRN, STUDENTS.SURNAME, STUDENTS.FORENAME, APP_STATUS.STATUS, METHODS.METHOD, JOBS.JOB_TITLE, APPLICATIONS.APP_DATE
FROM APPLICATIONS
JOIN STUDENTS
ON APPLICATIONS.SRN = STUDENTS.SRN
JOIN APP_STATUS
ON APPLICATIONS.STATUS_ID = APP_STATUS.STATUS_ID
JOIN METHODS
ON APPLICATIONS.METHOD_ID = METHODS.METHOD_ID
JOIN JOBS
ON APPLICATIONS.JOB_ID = JOBS.JOB_ID;
and here are the pictures of it in action
below is the code that does not show meaningful information but does work.
select "ROWID",
"APP_ID",
"SRN",
"STATUS_ID",
"METHOD_ID",
"JOB_ID",
"APP_DATE"
from "#OWNER#"."APPLICATIONS"
If i knew how to properly use rowid i am sure this is a simple feat but i dont so if i could get any help it would be useful
//edit
who ever renamed this to Application Expression why? what i am using is Apex Application Express it was relevant information that got changed to something wrong which might make it hard for someone with a similar problem to find later.
In the second, simple query, apex can determine which table (and record) you are trying to edit.
In the first query, with the joins, it can't tell which of the five tables in query you want to edit. You probably want to have the edit link pass the primary key of the row from APPLICATIONS to the child page. You would need to build into that page any logic (lists of values etc) that map lookup tables (such as status) to the values needed in the APPLICATIONS table.

CakePHP complex find from three tables dependent

I have three tables:
Stories (id, category_id, sub_category_id, name, story),
Categories (id, parent_id, lft. rght, name),
SubCategories (id, name)
They are properly related and all is working fine. But now I need to find stories which belongs to specified category and/or sub_category, by name autocompleate dialog. Example: user entered "dog bone" and must search for such a name in categories/subcategories and after find all stories whitch belongs to found categories. No problem when doing many finds, but in SQL I can make one query. Can this be done in CakePHP in one find ?
Thank you very much!
there are a few options for doing this, some of them below
a) linkable behavior - https://github.com/Terr/linkable/wiki
b) bindModel - http://mark-story.com/posts/view/using-bindmodel-to-get-to-deep-relations
c) adhoc-joins http://bakery.cakephp.org/articles/view/quick-tip-doing-ad-hoc-joins-in-model-find
read up on them and see what suites your needs best.
either you solve it with the table assocations or you use "containable" behavior.
"Containable" Behavior is very easy to use and easy to implement.
Containable Behavior in Cookbook

TSQL Query for analyzing Text

I have a table that has ordernumber, cancelled date and reason.
Reason field is varchar(255) field and it was written by many different sales rep and really hard to group by the reason category I need to generate a report to categorize cancelation reasons. What is the best way to analyse the reasons with TSQL?
Sample of reasons entered by sales rep
cust already has this order going out
cust can not hold for item Called to cancel order
cust doesn't want to pay for shipping
wife ordered same item from different vendor, sent email
cst made a duplicate order, sent email
cst can't hold
Cust doesn't want to go through verification process so is cancelling order
doesn't ant to hold for Bo
doesn't want
Cust called to cancel the order He can no longer get the product he wants
cnt hld
will not comply with export req
cant' hold
Custs request
Cust will not hold for BO
per. cust. request.
BTW I have SQL Server 2005.
part of your problem is that this these aren't truly reason codes. sounds like an issue with your schema to me. if there aren't predefined reason codes to reference and you're allowing free text entry for each reason, then there's really no way to do this directly, outside of pulling distinct reasons back, which is probably not going to be very useful.
just an idea, can you add another column to the table, even if it's in a temp or test environment and then give the business users the ability to assign a code (e.g. 1 for mis-ships, 2 for duplicate orders, 3 for wrong item etc.) to each order cancellation. then perform the analysis on that.
i assume that's what they're expecting from you, but i don't know that i see any better way. you could always perform the analysis yourself if you have the authority/knowledge but this might be painful if you have a ton of cancellations.
edit- i see now that you've tagged this with regex... it would be possible to setup specified keywords to pull out the entries, but there'd have to be some tolerance built in and still manual analysis afterwards for items which don't fall into any specified category due to misspellings etc. /edit
+1 to #jmatthews, you really need to have reason codes that are selected and then possibly allow free-form entry for the full reason.
If this isn't an option you can look into text clustering. Don't expect that to be fast or easy though, it's still an open research topic and is related to both AI and machine learning.
Look at Term Lookup in SSIS, here is an article to read.

What sort of database design would I need to use in case I wanted users to save tags, and be able to call already used tags?

I'm trying to implement a feature similar to StackOverflow's tag feature. That a user can create a new tag, or by typing pull up a list of similar tags already created.
This is such a wonderful feature on this site and I find it sad that most sites do not have something like this. It's both robust, and yet very very flexible and best of all: driven by the community.
So I have these two tables:
Company
id
email
name
companySize
countryOfOrigin
industryid
Industry
id
description
Every time a user writes a new tag, I want to create one with a unique ID, and also be able to search for existing tags.
Will this database design allow for an easy and efficient implementation of this feature?
If not, please give a little guidance. :)
Whilst there's not a tremendous amount of information to go on, what you've listed should be fine. (The 'tag' being the 'description' field in the industry table, etc.)
As you might imagine, all of the real work is done outside of SQL, where you'll need to...
(Potentially) add new tag(s) that don't yet exist.
Associate the industry with the supplied tag(s).
(Potentially) prune previously used tags that may no longer be in use.
...every time you edit an industry.
That said, the key limitation of your proposed setup is that each company can only belong to a single industry. (i.e.: It can only have a single industry tag associated with it.)
As such, you might want to consider a schema along the lines of...
Company
id
...
countryOfOrigin
Industries
id
description
CompanyIndustriesLookup
companyID
industryID
...which would let you associate multiple industries/tags with a given company.
Update...
For example, under this setup, to get all of the tags associated with company ID 1, you'd use...
SELECT Industries.description FROM (CompanyIndustriesLookup, Industries)
WHERE companyID=1 AND industryID=Industries.ID
ORDER BY Industries.description ASC;
On a similar basis, to get all companies tagged with an industry of "testing", you'd use...
SELECT Company.name FROM (Company, Industries, CompanyIndustriesLookup)
WHERE Company.id=CompanyIndustriesLookup.companyID
AND Industries.id=CompanyIndustriesLookup.industryID
AND Industries.description="testing"
ORDER BY Company.name ASC
A very easy (if somewhat suboptimal, but it often does not matter) solution to use tags is to not have tag ids at all. So, you have:
Items
ItemId
Name
Description
...
ItemTag
ItemId
Tag
Adding a tag to an item is just adding the tuple to the ItemTag table, whether the tag already exists or not. And you don't have to do any bookkeeping on removing tags either. Just keep an index on ItemTag.Tag, to be able to quickly display all unique tags.