Have a question. I have a database called scraped. It has two tables. One called profiles and the other called charges. There is an identifier for each person in the profiles table called ID and a corresponding identifier in the charges table called profile_id. I'd like to export the profiles table, but want to join up all the contents of the charges to make one big flatfile (or table) using the "use query" as an export method. I'm stumped as to how to do this.
One other issue. say john smith has ID of 101, he may have 10 rows In the charges table that correspond to his ID number. Will they all be listed in separate rows in final output or not? If not can they be somehow?
It sounds like you just need to write a simple join query.
SELECT [list of columns you need]
FROM Profiles
INNER JOIN Charges ON Profiles.ID = Charges.profile_id
If you need all profiles whether or not they have a charge then change INNER JOIN to LEFT JOIN.
And yes, you'll get a record for every match in the Charges table (so 10 for your john smith).
Related
I'm kinda new in databases and I need to solve this one:
client(NAME, CITY, STREET, NUMBER, BALANCE, CLIENT_CODE);
order(ORDER_NUMBER, CLIENT_CODE, PROVIDER_NAME, FUEL, QTY, DATE);
provider(PROVIDER_NAME, PROVIDER_ADRESS, FUEL_CODE, PRICE, STOCK);
fuel(FUEL_CODE, FUEL_NAME);
I've already tried (and succeeded I guess) to create an ALTER TABLE for provider and fuel named provider_fuel in order to solve many-to-many relationship, but I don't have any idea how I could create a connection between order and provider.
I've changed the entities like this:
provider(PROVIDER_ID, PROVIDER_ADRESS);
fuel(FUEL_CODE, FUEL_NAME);
provider_fuel(ID_ENTRY, ID_PROVIDER, ID_FUEL, PRICE, STOCK).
Is that even ok? If so, how can I make connections between all those entities in my database?
I have to mention that my app should allow clients to place orders from providers who have their specific fuels, prices and so on.
I would suggest the following table layouts:
address(ID_ADDRESS, CITY, STREET, NUMBER);
client(ID_CLIENT, NAME, ID_ADDRESS);
client_order(ID_CLIENT_ORDER, ID_CLIENT, RECEIVED_DATE);
client_order_detail(ID_CLIENT_ORDER_DETAIL, ID_CLIENT_ORDER, ID_PROVIDER, ID_PRODUCT,
ORDER_QTY, STATUS, DELIVERED_DATE); -- Status in ('OPEN', 'DELIVERED')
provider(ID_PROVIDER, NAME, ID_ADDRESS);
product(ID_PRODUCT, PRODUCT_NAME);
provider_product(ID_PROVIDER, ID_PRODUCT, PRICE, STOCK_QTY);
You can, if you like, expand this. For example, a provider might have multiple locations from which product can be supplied, in which case you'd need to re-work the single PROVIDER table into something like
PROVIDER(ID_PROVIDER, NAME)
PROVIDER_PRODUCT(ID_PROVIDER, ID_PRODUCT, PRICE)
PROVIDER_ADDRESS(ID_PROVIDER_ADDRESS, ID_PROVIDER, ID_ADDRESS)
and then rework PROVIDER_PRODUCT as
PROVIDER_ADDRESS_PRODUCT(ID_PROVIDER_ADDRESS, ID_PRODUCT, STOCK_QTY)
I suppose it's also possible that the price a provider charges might depend on the location from which it's shipped so you might need to change the model to accommodate that. The point is that there are many different ways to do this, and it depends very much on the requirements you have.
EDIT
To obtain the total value of an order using the tables above you'd use a query such as:
SELECT co.ID_CLIENT_ORDER, SUM(cod.ORDER_QTY * pp.PRICE) AS ORDER_TOTAL_VALUE
FROM CLIENT_ORDER co
INNER JOIN CLIENT_ORDER_DETAIL cod
ON cod.ID_CLIENT_ORDER = co.ID_CLIENT_ORDER
INNER JOIN PROVIDER_PRODUCT pp
ON pp.ID_PROVIDER = cod.ID_PROVIDER AND
pp.ID_PRODUCT = cod.ID_PRODUCT
GROUP BY co.ID_CLIENT_ORDER
ORDER BY co.ID_CLIENT_ORDER
You can put id_provider in order table and get the provider details by the id .For ex
Select *,p.price,p.fuel_code from order as o join provider as p on o.id_provider=p.id
Welcome to the Oracle database world!
You can make connections between tables or views using JOIN structure.
In your example, you can connect your tables like this:
SELECT od.* FROM order od, provider pd WHERE od.provider_name=pd.provider_name
Or you can write it like this. It's up to your style. But I prefer the first one.
SELECT od.* FROM order od INNER JOIN provider pd ON od.provider_name=pd.provider_name
But it's always better using NUMBER type columns in joins. So I suggest, create provider_id (NUMBER type) on 2 tables and join them.
There are 5 main types (INNER, OUTER, FULL, LEFT, RIGHT) of joins in SQL. Each of them provides different things.
If I understand correctly your database represents a market place where a client can buy different kinds of fuels from providers. So far you have used natural keys:
A client has some login code that identifys them (client_code).
A provider is identified by their name. Do you want this? That would mean a provider address stays constant and cannot change. That may or may not be desired. If the company JACOB'S FUELSHOP INC changes to THE FUELSHOP INC, do you want to treat it as the same company or a different one?
You also generate order numbers. Do you want them unique in your database, or per client or per provider? The order table's key would accordingly be either just order_number or order_number + client_code or order_number + provider_name.
Now you don't want to have one provider only sell one type of fuel, but various types. You introduce a bridge table. But in the same step you introduce technical IDs. Do you want to use technical IDs instead of natural keys?
You have provider(PROVIDER_ID, PROVIDER_ADRESS) where the provider's name is either missing or included in the address. This allows you to change the name later. But remember that you may want to store the name then with every order, as you may want to reprint it later or just say whether you placed the order with the legal company JACOB'S FUELSHOP INC or THE FUELSHOP INC. Technical IDs are fine, but you must remember to still keep unique constraints on the natural keys and think about consequences as the one just mentioned.
As to the fuel price: You are storing the current fuel price, but you are not storing the price when ordered. Add the price to the orders table.
As to your question: Order and provider are already linked by provider_name in the original design. In the new design you've introduced the provider_id. If you want to use this instead, put provider_id in the orders table. As mentioned, you may or may not want the provider name in that table, too.
The main idea is to store multiple ids from areas into one column. Example
Area A id=1
Area B id=2
I want if it is possible to save into one column which area my customer can service.
Example if my customer can service both of them to store into one column, I imagine something like:
ColumnArea
1,2 //....or whatever area can service
Then I want using an SQL query to retrieve this customer if contains this id.
Select * from customers where ColumnArea=1
Is there any technique or idea making that?
You really should not do that.
Storing multiple data points in a single column is bad design.
For a detailed explanation, read Is storing a delimited list in a database column really that bad?, where you will see a lot of reasons why the answer to this question is Absolutely yes!
What you want to do in this situations is create a new table, with a relationship to the existing table. In this case, you will probably need a many-to-many relationship, since clearly one customer can service more than one area, and I'm assuming one area can be serviced from more than one customer.
A many-to-many relationship is generating by connection two tables containing the data with another table containing the connections between the data (A.K.A bridge table). All relationships directly between tables are either one-to-one or one-to-many, and the fact that there is a bridge table allows the relationship between both data tables to be a many-to-many relationship.
So the database structure you want is something like this:
Customers Table
CustomerId (Primary key)
FirstName
LastName
... Other customer related data here
Areas Table
AreaId (Primary key)
AreaName
... Other area related data here
CustomerToArea table
CustomerId
AreaId
(Note: The combination of both columns is the primary key here)
Then you can select customers for area 1 like this:
SELECT C.*
FROM Customers AS C
WHERE EXISTS
(
SELECT 1
FROM CustomerArea As CA
WHERE CA.CustomerId = C.CustomerId
AND AreaId = 1
)
Can I use two joins between two tables in Access database?
I have a customer database, and my customer names appear in two different fields and I want to convert customer names into the short names and return that in a query in one single field.
In attempt to solve that I have created a second table with all the customer names and their abbreviations then linked "CustName" field with the "Customer_Name" field in my main table, in my query I am returning the short names of my customers. The struggle is that some customer names e.g Toyota appear in "customer_Plant" field instead of "customer_Name" field (please see picture). I want to use different Toyota shortnames by each plant location. Another difficulty is that the "Customer_Plant" field in my original table is not always populated, except for Toyota.
Is there any way I can use multiple relations between two different tables? so that access query can return short names, not just by "customer_Name" but also by "Customer_Plant" at the same time.
Access does not allow me to join "Customer_Plant" with "custPlant" if one join is present between the tables. Is there any other way I can achieve this?
Tbl_claimdata & tbl_custShortName:
Join between the tables:
Current Output:
If Plant name is not provided in either or both tables, consider:
Query1: Claims_ADJ
SELECT tblCustClaimData.Customer_Name,
tblCustClaimData.Customer_Plant, Nz([Customer_Plant],[Customer_Name])
AS LinkNameClaim FROM tblCustClaimData;
Query2: Short_ADJ
SELECT tblShortCustName.CustName, tblShortCustName.PlantName,
Nz([PlantName],[CustName]) AS LinkNameShort,
tblShortCustName.ShortName FROM tblShortCustName;
Query3:
SELECT Customer_Name, Customer_Plant, ShortName FROM Short_ADJ RIGHT
JOIN Claims_ADJ ON Short_ADJ.LinkNameShort = Claims_ADJ.LinkNameClaim;
Query3 is not updatable so probably useful only for a report.
So alternative is DLookup in query (queries 2 and 3 not needed) or textbox:
DLookUp("ShortName","tblShortCustName","Nz([PlantName],[CustName])='"
& Nz([Customer_Plant],[Customer_Name]) & "'")
I need to connect id_player from table Players to player_score and player_assist in table Goals. The primary key must refere to these two.
Is there any way how to do it?
Access writes me "The relationship already exist".
I will be grateful for every answer.
Access screen - Access
Is this the correct solution? - Possible solution
For each Foreign Key reference existing in a table; a separate join must be made to the main/base table to get the related data.
In your case; add Players again to your query and join it to the Goals.player_assist; while joining Players to Goals.Player_Score.
As to why: The same join can't get both pieces of data as they represent different relationships to the players table.
in SQL this would look like:
SELECT G.*
, PS.id_Player as ScoredByID_Player
, PS.first_name as ScoredByfName
, PS.last_name as ScoredBylName
, PA.id_Player as AssistedByID_Player
, PA.First_name as AssistedByfName
, PA.Last_name as AssistedBylName
FROM GOALS G
INNER JOIN Players PS
on G.id_Player = PS.Player_Score
LEFT JOIN Players PA
on G.id_Player = PA.Player_Assist
Note we alias the field names from players so we know which is scored by and which is assisted by. We also alias the tables for readability and because we have to copies of "Players" and for the engine to keep track of which table we mean; we have to have them "named" differently.
The reason why I LEFT join (outer) the second time, is because not all scores have an assist; but all scores have someone scoring them. So the first join to players can be an inner join but the second join may not have an assist; and we still may want to see details for all goals made. If we made the 2nd join an inner one, we would lose all scores where an assist wasn't involved.
I have a database with two tables: Users and Categories.
Users has these fields:
UserId unique identifier
UserName nvarchar
CategoryId int
Categories has these fields:
CategoryId int
CategoryName nvarchar
At the moment, every user is in one category. I want to change this so that each user can be in any number of categories. What is the best way to do this?
My site does a lot of really expensive searches, so the solution needs to be as efficient as possible. I don't really want to put the list of categories each user has in a third table, as this means that when I pull back a search, each user will be represented in several rows at once (at least, this is what would happen if I implemented a search with my current, fairly crude, understanding of sql.)
EDIT:
If setting up a many-many relationship, is it possible to return only one row for each user?
For instance:
DECLARE #SearchUserID nvarchar(200) = 1;
SELECT *
FROM Users JOIN Categories JOIN CategoriesPerUser
WHERE UserId = #SearchUserID
This would return one row for each category the user belonged to. It is possible to have it only return one row?
At the moment you have a one-to-many relationship, that is to say category can be assocaited with many users, but a user can only be assocaited with one category.
You need to change this to a many-to-many relationship so that each user can be assocaited with many categories and each category can be assocaited with many users.
This is achieves by adding a table which links a userid and a category id (and removing categoryid from the user table)
Table: UserToCategory
UserId int
CategoryId int
As for your last paragraph, this is the most efficient way of modelling your requirement. You should make a combination of UserId/CategoryId the PrimaryKey in this table to stop a user being associated with the same category twice. This stops the problem of a user returned twice for a particular category.
The SQL to find, for example, all users associated with a category would be
SELECT u.*
FROM Users u
INNER JOIN UserToCategory uc
ON u.UserId = uc.UserID
WHERE uc.CategoryId = 123
Edit after comments: If you have a query that finds a number of users, and you want a distinct list of categories associated with those users this could be done like
SELECT c.*
FROM Categories c
WHERE CategoryId IN
(
SELECT uc.CategoryID
FROM UserToCategory uc
INNER JOIN Users u ON uc.UserId = u.UserID
WHERE <some criteria here to filter users>
)
I would drop CategoryId out of Users and go for the 3d table:
UserCategories
- UserId
- CategoryId
If you want to search all the categories for a user you can use for example:
SELECT uc.CategoryId, c.CategoryName
FROM UserCategories uc
JOIN Categories c ON uc.CategoryId = c.CategoryId
WHERE uc.UserId = #UserId
As this is an n-to-n Relationship (one category can have several user and one user can have several categories), the typical way to implement this would be to have a junction table.
But as you said, you don't want to create a third table for reasons of already implemented features, i guess you could also change the column "CategoryId" in the User table to "CategorieIds", which could then contain a text field. This text field could contain a list of integers, separated by a special character ("," for example). as far as i'm concerned, you should then do the split operation on your implementing code, since i don't know of any practical way to do this in sql (maybe someone could correct me here...).
You could also keep you categoryId Column then, if you wanted to implement something like a 'main' category per user.
Hope this helps and I hope to have suggested a correct way to implement this!