So I have two access tables:
Jobs Table:
JobID,
Customer,
Address,
Measure Date,
Install Date
Job Items:
JobID,
Item Name,
Item Length,
Item Width,
Item Quantity,
Item Cost
So what I want to do is add a field to the Jobs Table that shows the Total Value of all of the Item Costs with the same JobID.
How do I do this?
Edit:
Jobs:
+----+-------------+-----------------+--------------+--------------+
| ID | Customer | Address | Measure Date | Install Date |
+----+-------------+-----------------+--------------+--------------+
| 1 | Josh Manson | 22 Louis Lane, | 13/08/2016 | 27/08/2016 |
+----+-------------+-----------------+--------------+--------------+
Job Items:
+------------+-------------------------+-------------+------------+---------------+--------------------+
| Job Number | Item Name | Item Length | Item Width | Item Quantity | Item Material Cost |
+------------+-------------------------+-------------+------------+---------------+--------------------+
| 1 | Security Screen | 800 | 600 | 2 | $250.00 |
| 1 | Window, white aluminium | 700 | 400 | 3 | $150.00 |
+------------+-------------------------+-------------+------------+---------------+--------------------+
I would like there to be an extra column in the first table that adds all the Item Costs for that ID. For JobID 1 it would have a value of $400.
Sorry I'm not quite sure how to format tables properly in StackOverflow.
Create a query in the query designer, with both tables and their INNER JOIN.
Add functions/grouping by clicking the "Totals" button.
Add all fields from the Jobs table, they will all be set to "Group by".
Add Item Material Cost from the Items table, and set its "Total" to Sum.
That's it (well, you should set a column title for the sum column, or it will show in the query result as SumOfItemMaterialCost or something).
Related
I have a table products and a table locations which are linked together in a many-to-many relationship with a table products_locations. Now a client can select a set of products, and I want to run a query that selects only the locations, where ALL of the selected products are available.
This seemed pretty straight forward at first, but I see myself being quite baffled by how to achieve this. I initially thought I could get all the correct location-ids with something like
SELECT location_id
FROM products_locations
WHERE product_id = ALL [the user selected product ids]
But on second thought that does not appear to make sense either (the structure of products_locations is quite simply [product_id, location_id].
Any suggestion on how to structure such a query would be appreciated. I feel like I am overlooking something basic..
EDIT: I am using mysql syntax/dialect
Quick sample: Given the following tables
| products | | locations | | products_locations |
| id | name | | id | name | | product_id | location_id |
|------------| |-----------| |--------------------------|
| 1 | prod1 | | 1 | locA | | 1 | 2 |
| 2 | prod2 | | 2 | locB | | 2 | 1 |
| 3 | prod3 | |-----------| | 2 | 2 |
|------------| | 3 | 1 |
|--------------------------|
If a user selects products 1 and 2, the query should return only location 2. If the user selects products 2 and 3, the query should return location 1. For 1, 2, and 3, no location would be valid, and for product 2, both locations would be valid.
I figured out a query that achieves what I need. Though it is not as clean as I had hoped, it seems to be a robust approach to what I'm trying to query:
SELECT t.location_id
FROM (SELECT location_id, COUNT(*) as n_hits
FROM products_locations
WHERE product_id IN [the user selected products]
GROUP BY location_id) t
WHERE n_hits = [the number of user selected products];
Explanation:
I create a temporary table t which contains every location_id that has at least one matching product in the user's selection, together with the number of times that location matches a product in the user's selection. This is achieved by grouping the query by location_id.
I select the location_id(s) from that temporary table t, where the number of hits is equal to the number of products the user had selected. If that number is lower, I know that at least one product did not match that location.
I'm developing an in-game shop for the game Minecraft, in which an item is defined as a pair of a Material string and a Data integer. Each advertised item is inserted in a table of a MySQL database with a price integer associated to it and the same item can be advertised multiple times with the same price or not, like in the example below, where the items (ink_sack, 3) and (apple, 0) appear twice:
+----------+------+-------+
| material | data | price |
+----------+------+-------+
| ink_sack | 0 | 1 |
| ink_sack | 3 | 2 |
| ink_sack | 3 | 6 |
| apple | 0 | 2 |
| apple | 0 | 5 |
|iron_sword| 0 | 10 |
What I want is to retrieve the entry for each possible item (pair of Material and Data) with the lowest price, like in the following example:
+----------+------+-------+
| material | data | price |
+----------+------+-------+
| ink_sack | 0 | 1 |
| ink_sack | 3 | 2 |
| apple | 0 | 2 |
|iron_sword| 0 | 10 |
However, I don't have any idea of how to do that considering these pairs of values instead of a single column when using the LEAST keyword or even if thats the right option in this case. How should I do that with a single query and no post-processing?
Group the records by the columns you want to be unique. aggregate functions like min() apply to each group
select material, data, min(price) as min_price
from your_table
group by material, data
Try this query !
Here I am using 'GROUP BY' clause which makes the group according to the data & material in the table ,then apply the aggregate function of minimum 'min' on the price column of group data & sort it by price using 'ORDER BY' clause.
Also I am attaching the screenshot of the result of query.
SELECT
material ,
data ,
min(price) AS price
FROM
[Table Name]
GROUP BY
data ,
material
ORDER BY
price
I have a MySQL database with the following tables:
Items (ItemId, ItemName)
Item1 (Time, Value)
Item2 (Time, Value)
Item3 (Time, Value)
Item4 (Time, Value)
.
.
ItemX (Time, Value)
subscriptions (sub_id, sub_topic, pin, item_id, device_id)
The item_id in subscriptions table is foreign key to ItemId in Items table.
The numbered Item tables have state information on when the item was turned ON or OFF. All the Item tables are generated and I run the risk of breaking something if I modify them.
I want to be able to get all rows of a specific device_id from subscriptions and join it with the last recorded state from the corresponding Item table, like so:
+--------+-----------+-----+---------+-----------+-------+
| sub_id | sub_topic | pin | item_id | device_id | value |
+--------+-----------+-----+---------+-----------+-------+
| 1 | topic1 | 5 | 1 | 1 | OFF | <-- Last recorded Value from Item1
| 2 | topic2 | 4 | 4 | 1 | OFF | <-- Last recorded Value from Item4
| 3 | topic3 | 14 | 3 | 1 | ON | <-- Last recorded Value from Item3
| 4 | topic4 | 12 | 2 | 1 | ON | <-- Last recorded Value from Item2
+--------+-----------+-----+---------+-----------+-------+
I am using the following queries to get all rows of a specific device_id and then manually get the last recorded state for each row:
SELECT * FROM subscriptions WHERE device_id=1;
SELECT Value FROM Item1 WHERE Time=(SELECT MAX(Time) FROM Item1);
But I do not know how to combine the two to get what I want. The name of the table to check the state has to be determined dynamically based on the item_id of each row from the first query.
I have created the tables in SQLFiddle to make it easier for someone to help me with this.
http://sqlfiddle.com/#!9/392fe
I am trying to write a mySQL statement that selects data from one table but counts up entries from another table with a matching ID in a specific field.
The two tables are jobs and job_cards. A job will always be a single entry which will have multiple job cards, so I need to write a singular statement that selects data from the job table but adds another field in the result which is a count of all related job cards.
Example:
jobs table:
| ID | customer | status | date_added |
|----------------------------------------|
| 1 | 3 | active | 2017-10-10 |
------------------------------------------
job_cards table is a bit more complex but includes a column called job_id which will be 1 in this case. But lets say there are 3 cards assigned to the job above. I wrote the following statement:
SELECT j.*, COUNT(jc.id) AS card_count FROM jobs j LEFT JOIN job_cards jc ON j.id = jc.job_id
But the count column only returns the TOTAL number of cards in the job_cards table, regardless of which job they are assigned to. Not only that, but it only ever returns a single result even though at the moment there are 4 entries in the jobs table.
Is there any way to do what I need to do with a single statement?
EDIT:
Sample data from the job_cards table:
| ID | job_id | customer | description | materials | notes |
|--------------------------------------------------------------|
| 1 | 1 | 3 | blah blah | none | test |
| 2 | 1 | 3 | something | pipes | n/a |
----------------------------------------------------------------
The result I would like to get is:
| ID | customer | date_added | card_count |
|-------------------------------------------|
| 1 | 3 | 2017-10-10 | 2 |
---------------------------------------------
Where the ID here is the ID of the job.
You can try this:
SELECT *, (select count(*)
from job_cards jc
where jc.job_id=j.id) as card_count
FROM jobs j
I'm doing a kind of point-of-sale system whose MySQL database has (among other things) a table with items for sale, a table with sales, and a table with purchases (a purchase being my ad-hoc notation for any single item bought in a sale; if the same person buys three items at once, for example, that's one sale consisting of three purchases). All these tables have logical IDs, viz. item_id, sale_id, purchase_id, and are easily joined with simple pivotal tables.
I am now trying to add a discount feature; basically your garden-variety supermarket discount: buy these particular items and pay X instead of paying the full sum of the regular item prices. These 'package deals' have their own table and are linked to the items table with a simple pivotal table containing deal_id and item_id.
My problem is getting to the point of figuring out when this is to be applied. To give some example data:
items
+---------+--------+---------+
| item_id | title | price |
+---------+--------+---------+
| 12 | Shoe | 10 |
| 76 | Coat | 23 |
| 82 | Whip | 19 |
+---------+--------+---------+
sales
+---------+-----------+
| sale_id | timestamp |
+---------+-----------+
| 2973 | 144995839 |
| 3092 | 144996173 |
+---------+-----------+
purchases
+-------------+-------------+---------+----------+---------+
| purchase_id | no_of_items | item_id | at_price | sale_id |
+-------------+-------------+---------+----------+---------+
| 12993 | 1 | 12 | 10 | 2973 |
| 12994 | 1 | 76 | 23 | 2973 |
| 12996 | 1 | 82 | 19 | 2973 |
| 13053 | 1 | 12 | 10 | 3092 |
| 13054 | 1 | 82 | 19 | 3092 |
+-------------+-------------+---------+----------+---------+
package_deals
+---------+-------+
| deal_id | price |
+---------+-------+
| 1 | 40 |
+---------+-------+
deals_items
+---------+---------+
| deal_id | item_id |
+---------+---------+
| 1 | 12 |
| 1 | 76 |
| 1 | 82 |
+---------+---------+
As is hopefully obvious from that, we have a shoe that cost $10 (let's just assume we use dollars as our currency here, doesn't matter), a coat that costs $23, and a whip that costs $19. We also have a package deal that if you buy both a shoe, a coat, and a whip, you get the whole thing for $40 altogether.
Of the two sales given, one (2973) has purchased all three things and will get the discount, while the other (3092) has purchased only the shoe and the whip and won't get the discount.
In order to find out whether or not to apply the package-deal discount, I of course have to find out whether all the item_ids in a package deal are present in the purchases table for a given sale_id.
How do I do this?
I thought I should be able to do something like this:
SELECT deal_id, item_id, purchase_id
FROM package_deals
LEFT JOIN deals_items
USING (deal_id)
LEFT JOIN purchases
USING (item_id)
WHERE
sale_id = 2973
AND item_id IS NULL
GROUP BY deal_id
In my head, that retrieved all rows from the package_deal table where at least one of the item_ids associated with the package deal in question does not have a corresponding match in the purchases table for the sale_id given. This would then have told me which packages don't apply; i.e., it would return zero rows for purchase 2973 (since none of the items associated with package deal 1 are absent from the purchases table filtered on sale_id = 2973) and one row for 3092 (since one of the items associated with package deal one—namely the coat, item_id 76—is absent from the purchases table filtered on sale_id = 3092).
Obviously, it doesn't do what I naïvely thought it would—rather, it just always returns zero rows, no matter what.
It doesn't really matter much to me whether the resulting set gives me one row for each package deal that should apply, or one for each package deal that shouldn't apply—but how do I get it to show me either in a single query?
Is it even possible?
The problem with your query above is that sale_id is also NULL in the missing row that you're interested in, due to the LEFT JOIN.
This query will return the deal_id for any deals that DO NOT apply to a given order:
SELECT DISTINCT
pd.deal_id
FROM package_deals pd
JOIN deals_items di on pd.deal_id = di.deal_id
WHERE di.item_id NOT IN (SELECT item_id FROM purchases WHERE sale_id = 3092)
From that it's easy to work out the ones that do apply. Note that for a fully functioning system, you'd still need to take the purchase quantities into account - e.g. if the customer had bought 2 of two the items in the deal, but only 1 of the third... etc.
A SQL fiddle demonstrating the query is here: http://sqlfiddle.com/#!9/f2ae4/8
Note that I've made my joins using the ON syntax, as I'm simply more familiar than with USING. I expect that would work too if you prefer it.