I need to compile quantities from several warehouses that update their inventories periodically. The files are automatically loaded into tables in my MySQL database, but sometimes one warehouse might have a few more or less files than the others. I need to add them all to determine the total quantity available from the entire network.
My idea was to do:
SELECT
IFNULL(branch_01.qty,0) +
IFNULL(branch_02.qty,0) +
IFNULL(branch_03.qty,0) +
etc. through all warehouses joined as:
FROM branch_01
JOIN branch_02
USING (oespaced)
JOIN branch_03
USING (oespaced)
etc. through all warehouses
I can't use LEFT JOIN or RIGHT JOIN because sometimes one warehouse might have missing entries and sometimes another might. If a sku is missing from one branch's file, I'd prefer to still have the other branches added together, and just get a NULL, which would be converted to a 0 by the functions in the SELECT. When I've tested different joining solutions, I also seem to be getting Cartesian numbers of rows, which confuses me further.
Any guidance is greatly appreciated.
Just a little clarification:
We need to join 17 tables. We're not really concerned with the sum of a column, but more the individual values. For instance, a table might represent a list of items a,b,c,d, and list quantities of 1,2,3,4. We would have that table from several different warehouses and we would need to find a total for the entire network. If four warehouses had those values, we would want to see a,b,c,d with 4,8,12,16 as values for the total available.
I don't understand your question fully but hope my answer helps you a bit.
Are you joining many tables? So let's say 2 tables and you want to sum up the quantity column?
First of all, JOIN performs the cartesian product of 2(or more) tables. So you'll get so many instances that you don't wish to have; the solution to this is using the WHERE.
Maybe this is what you are looking for:
SELECT sum(a.qty) + sum(b.qty)
FROM table1 a, table2 b
WHERE a.pk = b.fk -- this one resolves the unwanted instances
fk denotes foreign key and pk denotes primary key.
Related
I was hoping someone could help me come up with a query for what I'm looking to do.
I have a website that lists game servers and I'm trying to improve my search system a bit.
There's three tables of interest; servers, version_taxonomy and category_taxonomy. The taxonomy tables contain two columns, one for a server ID and one for a version/category ID, where associations between a server and it's supported versions and categories can be made.
Up till now, I've been joining both taxonomy tables to the server table and be looking up servers for one version and one category, it's been working fine. However I'm looking to allow the search of a server that has multiple categories at the same time.
I've made an image to try and illustrate what I'm looking to do:
Say I'm looking for a server that has both categories 5 and 12 - Based on the table on the left that would be servers 1 and 3. But how would that be in a query? And how would I use that query to later get and work with the rest of the server data (JOIN like I'd normally do?)
Hopefully that makes sense! Looking forward to your responses.
Assuming I understand the question:
Join the two tables then count the distinct values of category ID while limiting by them. Distinct is not be needed if you can guarantee the uniqueness of serverID, categoryID from table A and a 1:1 relationship to server taxonomy which would be true if you always limit by 1 and only 1 version...
SELECT A.ServerID, count(A.CategoryID) CatCnt
FROM A
INNER JOIN B
on A.ServerID = B.ServerID
WHERE A.CATEGORYID in (5,12)
and B.Version= 1.16
GROUP BY A.ServerID
HAVING count(distinct A.CategoryID) = 2
The category ID could be parameter passed in as well as the count distinct as you know both values.
This could be used as a CTE or as a inline derived table as a source then join in to get the addiontal data; or left join in the desired data assuming it's a 1:1 relationship.
If you want a working example: post DDL for table and SQL to create sample data and I'll put something in https://rextester.com/.
I have a MySQL database with a table for products and a table with the buying/selling history of these products. The buying and selling history of each product is basically tracked in this history table.
I am looking for the most efficient way of creating a list of these products with the earliest transaction data from the history table joined.
At the moment my SQL query selects the products with the earliest history entry like this:
SELECT p.*
, h.transdate
, h.sale_price
FROM products p
LEFT
JOIN
( SELECT MIN(transdate) transdate
, product_id
FROM history
GROUP
BY product_id
) hist_min
ON hist_min.product_id = p.id
LEFT
JOIN history h
ON h.product_id = hist_min.product_id
AND h.transdate = hist_min.transdate
Since this query is used very frequently and potentially with many products I am considering storing the first sale_price directly in the 'products' table. This way I wouldn't need the 2 additional JOINS at all. But this would mean I store redundant data.
For me the most important question is, which of these possibilities is the most efficient one.
I am not sure if I am allowed to ask this additionally, but if there is an even better way I would like to know about it.
EDIT: To clarify 'efficient', I am talking about tens of thousands of products with maybe 10 history records each, where I only pick pagewise 20 with a LIMIT statement. To save the original price with the product would be pulling the data straight with the record, while the scanning of dates in the history table for the earliest time and another scan to join the actual row of data would require certainly more resources, even if only for the second table involved. The use of a primary key ID oder an index over product_id and transdate would certainly speed up the second join though.
What you're describing is called 'normalization'. The level of normalization is not a black and white area so I don't think this site is the place to get your answer as it's primarily opinion based.
Check out these links to get started:
Database Normalization Explained in Simple English
Wikipedia (check out the 'See also' section, it describes level of normalization)
I have two tables that have different data that I need to merge. They do have similarities such as: Order number, Name, type or product. But they have separate data as well like: Order date, and Engravings.
Would I do two separate Append queries in Access into a merged table? Or one Append queries? Or just keep the data separate?
I am new to Access and trying to find the best way to approach this.
Merging the two tables into one completely defeats the purpose of using a database and you're better off using excel at that point. You want to split the data as much as possible along logical lines so that you can find, say... all the orders that Mr X has ever made for a specific product. And in that case you're going to want to have separate tables for customers, orders, engravings and the like.
The best practice from a design standpoint is to place fields that each table has in common into a third "master" table, then create relationships from that table to the existing tables and delete the data that has been transferred to the main table (except for the primary keys, which have to be common with your master table).
To create the master table, use a Make Table query to generate the master table based on one of your tables, then an append query to add any products in the master table that might not be common to both, based on the other table. Finally, delete queries for each table would rid you of redundant data in both original tables.
However, I strongly suggest you use Microsoft's tutorials and download the NorthWind sample database so you can get an idea of what a properly structured database looks like. The beginner's learning curve for access is very steep and having well built example databases is almost a requisite.
Make a backup of your database(s) and play with it until it turns out right. Do not make the mistake of playing with live data until you know what you're doing.
As you have similar fields on either table, take the Order number field from both tables using a union query. Something like:
SELECT tbl_Delivery_Details.OrderNo
FROM tbl_Delivery_Details
GROUP BY tbl_Delivery_Details.OrderNo
UNION
SELECT tbl_Delivery_Header.[Order number]
FROM tbl_Delivery_Header
GROUP BY tbl_Delivery_Header.[Order number];
This would take the order numbers from the delivery details table and from the delivery header table and merge them into one list with only one instance of each order number. Save the query.
You could then use this query in a new query. Bring in your 2 tables to this query and insert the fields from either table that you require.
As users add records to the tables they will be added to the union selet query when it is next run.
PB
It depends on what you want to do. Let's assume you have tables A (with 50 records) and B (with 75) records, and both tables have a similar column called OrderID.
Appending Rows:
If you want to create a table with 125 total records by combining records (rows) from A and records (rows) from B, run the following two queries:
Query 1:
SELECT A.ORDER_NUMBER, A.TEXT_FIELD1 as DATA INTO C
FROM A;
Query 2:
INSERT INTO C ( ORDER_NUMBER, DATA )
SELECT B.ORDER_NUMBER, B.TEXT_FIELD2
FROM B;
Appending Columns: If you want to create a table with 75 total records where you are appending columns from A to the columns in B, then run the following query:
SELECT B.ORDER_NUMBER, A.TEXT_FIELD1, B.TEXT_FIELD2 INTO C
FROM A RIGHT JOIN B ON A.ORDER_NUMBER = B.ORDER_NUMBER;
... in a similar way, you can append columns in B to columns in A in a new table C with a total of 50 records by running the following query:
SELECT A.ORDER_NUMBER, A.TEXT_FIELD1, B.TEXT_FIELD2 INTO C
FROM A LEFT JOIN B ON A.ORDER_NUMBER = B.ORDER_NUMBER;
some help here please with (advanced) mysql. Example illustrates the issue much better. So..
I have a predefined value pair table PARTNERS with partner1 and partner2 columns. And then there is another table PROJECTS which has partner1 and partner2 columns.
So, I want to select all PROJECTS where columns partner1 and partner2 are within the actual partners table described above.
Obviously, I cannot simply indicate "where partner1=... and/or partner2=..." because there would be no check of whether those two are partners (as defined in the PARTNERS table). (Just in case: there are projects with partner1 and partner2 not in the partner relationships.)
I don't think that kind of query is possible at all since it has the condition stored in the result. But would be happy if one can prove otherwise.
Thanks
It sounds like you need a query that will give you rows from PROJECTS where partner 1 and partner 2 are both the same as they are in any row in PARTNERS. So do an inner join:
SELECT * FROM projects
INNER JOIN partners
ON projects.partner1 = partners.partner1
AND projects.partner2 = partners.partner2
If you're up for restructuring your tables, it might make more sense to assign a unique ID to every row in PARTNERS, and use that ID in the PROJECTS table. That way instead of storing two columns of redundant data, you just have one column indicating which pair of students is on the project.
I am applying a group of data mining algorithms to a dataset comprised of a set of customers along with a large number of descriptive attributes that summarize various aspects of their past behavior. There are more than 10,000 attributes, each stored as a column in a table with the customer id as the primary key. For several reasons, it is necessary to pre-compute these attributes rather than calculating them on the fly. I generally try to select customer with a specified attribute set. The algorithms can combine any arbitrary number of these attributes together in a single SELECT statement and join the required tables. All the tables have the same number of rows (one per customer).
I am wondering what's the best way to structure these tables of attributes. Is it better to group the attributes into tables of 20-30 columns, requiring more joins on average but fewer columns per SELECT, or have tables with the maximum number of columns to minimize the number of joins, but having potentially all 10K columns joined at once?
I also thought of using one giant 3-column customerID-attribute-value table and storing all the info there, but it would be harder to structure a "select all customers with these attributes-type query that I need."
I'm using MySQL 5.0+, but I assume this is a general SQL-ish question.
From my expirience using tables with 10,000 columns is very-very-very bad idea. What if in future this number will be increased?
If there are a lot of attributes you shouldn't use a horizontal scaled tables (with large number of columns). You should create a new table attributes and place alltributes values into it. Then connect this table with Many-To-One relationship to main entry table
Maybe the second way is to use no-SQL (like MongoDB) systems
As #odiszapc said, you have to use a meta-model structure, like for instance:
CREATE TABLE customer(ID INT NOT NULL PRIMARY KEY, NAME VARCHAR(64));
CREATE TABLE customer_attribute(ID INT NOT NULL, ID_CUSTOMER INT NOT NULL, NAME VARCHAR(64), VALUE VARCHAR(1024));
Return basic informations of given customer:
SELECT * FROM customers WHERE name='John';
Return customer(s) matching certain attributes:
SELECT c.*
FROM customer c
INNER JOIN attribute a1 ON a1.id_customer = c.id
AND a1.name = 'address'
AND a1.value = '1078, c/ los gatos madrileƱos'
INNER JOIN attribute a2 ON a2.id_customer = c.id
AND a2.name = 'age'
AND a2.value = '27'
Your generator should generate the inner joins on the fly.
Proper indexes on the tables should allow all this engine to go relatively fast (if we assume 10k attributes per customer, and 10k customers, that's actually pretty much a challenge...)
10,000 columns is much. The SELECT statement will be very long and messy if you wouldn't use *. I think you can narrow the attributes down to most useful and meaningful ones, eliminating others