Update query (access & vb.net) - vb.net

QUESTION 1
I have to update some fields of a table of access according to the value of parameter. If this paramter is "true" I need to update.
Table
idInvoice
price
percentageTax1
tax1
percentageTax2
tax2
total
Example values:
idinvoice: 12300
price: 100 €
percentageTax1: 10 %
tax1= 10€
percentageTax2: 5 %
tax2: 5€
total: 115 € (result: 100€+10€+5€)
Ok. If the parameter on that I have commented before is "true" I must update the percentages and then update the total. I need to replace the "old" percentages by new percent.
Ok I can do it in 3 queries:
update invocies set percentageTax1=20,tax1=price *(percentageTax1/100) where idInvoice=#number and percentageTax1=10
update invocies set percentageTax2=7,tax2=price *(percentageTax2/100) where idInvoice=#number and percentageTax2=5
update invocies set total=price+tax1+tax2 where idInvoice=#number
. But my question is:
is there any an alternative to do this in 1 query?
QUESTION 2
Other question about update.
If I have 2 linked tables
EXAMPLE TABLE INVOICE
idInvoice
total
EXAMPLE TABLE DETAIL
idInovice
Line
price
The "total" field is the total sum of the field "price" of the table "detail"
how it would be the "query" to update "total" field?
TOTAL field need to be stored in database
SOLUTION QUESTION 2:
is possible if I do this query. Example.
update table1 INNER JOIN table2 ON table1.id=table2.id set table1.field1=table2.fieldX

It is more common to pull out the invoice you want to work on, do the maths in the code to update the values, then put all the updated values back in the database in one go.
There are a thousand different ways of doing this!
possibly one place to start is http://code.msdn.microsoft.com/eisk
or here
http://www.asp.net/data-access/tutorials/an-overview-of-inserting-updating-and-deleting-data-vb

In answer to Question two.
Unless there is some special need to store the calculated result in the database I would just calculate it each time I wanted to do anything with the total.
This may not scale if you are writing StackOverflow, but for normal use it saves a place where data can slip out of sync.

Get rid of the calculated fields if possible.
update invocies
set percentageTax1 = IIf(percentageTax1=10, 20, percentagetax1)
, percentageTax2 = IIf(percentageTax2=5, 7, percentageTax2)
where idInvoice=#number AND (percentageTax1=10 OR percentageTax2=5)

Related

SQL: getting rows where some 'x' column value is a maximal one [duplicate]

This question already has answers here:
How can I SELECT rows with MAX(Column value), PARTITION by another column in MYSQL?
(22 answers)
Closed 11 months ago.
I am trying to get data from my database.
Query upon sub-query upon another sub-query - and as the intermediate result I get looks like this:
item
quantity
pen
34
pencil
42
notebook
42
eraser
12
I need to build another query upon this result set to get the rows where item_quantity has it's maximal value (42 in the example above). The rows with pencils and notebooks. However, I have found out that the task is a bit trickier than I expected it to be.
SELECT * FROM sub_query_result HAVING quantity = MAX(quantity)
always returns an empty result set
SELECT * FROM sub_query_result HAVING quantity = 42
is pointless since I need to know the exact max quantity in advance
SELECT * FROM sub_query_result WHERE quantity = MAX(quantity)
simply works not ("Invalid use of group function")
I can see solutions that work but that I do not like -- due to extra actions I need to take on my back-end code that executes this sql request, or due to their inefficiency:
I can create a temporary table, get max. quantity from it and place to a variable. Then I can use this variable inside the query to that temporary table and get the data I need.
I can do
SELECT * FROM query_result HAVING quantity = (SELECT MAX(quantity) FROM
<Query upon sub-query upon another sub-query that shall return query_result>)
but that way I request the very same data twice! which in general is not a good approach.
So... Anything I missed? Any simple and elegant solutions that can solve my problem?
Order by quantity descending to get the max values first. Only select the first row, i.e. the one having the max values. ANSI SQL version:
SELECT * FROM query_result
ORDER BY quantity DESC
FETCH FIRST 1 ROW WITH TIES
WITH TIES means you can get several rows, if there are several rows having the same maximum quantity.

Tableau: Get the ids that contain only the selected values from another column

I have the following question!
I have a table like this:
Data Source
I want to create a field(i suppose it's a field) that i can take the apl_ids,
that have as service_offered some that i want.
Example from the above table. If i want the apl_ids that have ONLY the service_offered
Pending 1, Pending 2 and Pending 7.
In that case, I want to get the apl_id = "13" since apl_id = "12" got one more service that i don't need.
Which is the best way to get that?
Thank you in advance!
Add a calculated field which gives 1 for desired values and 0 for other values. Add another calc field with fixed LOD to apl_id to sum of calcF1. Filter all ids with values=3 only. I think that should work.
Else tell me I will post screenshots
You can create a set based on the field api_id defined by the condition
max([service_offering]=“Pending 1”) and
max([service_offering]=“Pending 2”) and
max([service_offering]=“Pending 7”) and
min([service_offering]=“Pending 1” or [service_offering]=“Pending 2” or [service_offering]=“Pending 7”)
This set will contain those api_ids that have at least one record where service_offering is “Pending 1” and at least one record with Pending 2 ... and where every record has a service offering of 1, 2 or 7 (I.e. no others)
The key is to realize that Tableau treats True as greater than False, so min() and max() for boolean expressions correspond to every() and any().
Once you have a set of api_ids() you can use it on shelves and in calculated fields in many different ways.

SQL in Access, subquery pairing issue

I wrote an SQL statement in Access that looks for rows of data with the same value in their 'Code' column and then looks at those rows with the same 'Code' value and finds rows with opposite 'Money Amt' column values (for example one row would have a value of 200 and another would have -200) a column labeled line is then populated with the number '999' when pairs of these opposite values with the same code are found.
The problem is that some of my rows are pairing in odd numbered groups instead of by pairs of 2. I want there to be a 1:1 relationship for the opposing values so that they essentially negate each other.
Here is the code I used to get the result so far.
UPDATE [Actual Debt]
SET LineItem = 999
WHERE EXISTS
(SELECT * FROM [Actual Debt] as ad2
WHERE ad2.Code = [Actual Debt].Code
AND ad2.[Money Amt] = - [Actual Debt].[Money Amt]);
In the picture you can see that in the first 4 rows the code populated 2 pairs of opposing 'Money Amt' values as intended. But, in the bottom 3 rows there should have only been 1 pair of '999', but instead it has populated an odd number of rows.
How do I get the subquery to only populate the Line field for opposing pairs.
Image from before I put in the current code
Thank you in advance.
Now Gordon I do believe this can be done in MS Access. You can do just about everything in Access that you can do in other database its just a matter of figuring out the how. However in this particular case there seems to be a problem with the underlying data that is causing the current issue and without seeing the entire source table it is very hard to determine what that error is. Still I would venture to guess that if you ran your sub-Query by itself (as I show below) that you would get the data as I show below. Try running just the SELECT part of your query and see what you get.
SELECT *
FROM ActualDebt AS Ad2
WHERE Ad2.Code = ActualDebt.Code
AND Ad2.MoneyAmt = ((-1) * ActualDebt.MoneyAmt);
Most likely the Query Results are as follows based on what I see in your table
Code | MoneyAmt
MHT .3
MHT .3
MHT -.3
MHT -.3
RLO .4
RLO .6
MQR .9
MQR -.9
MQR .9
So Gordon if what I have outlined above, is the issue, then yes you will need to provide more information in order for a solution to be determine because programmatically right now there would be no way to differentiate between the first MQR .9 and the other MQR .9 -- which seems to be the source of the issue
I will keep an eye on this post and if you edit your question then I will edit this answer to help.

T-SQL query for SQL Server 2008 : how to query X # of rows where X is a value in a query while matching on another column

Summary:
I have a list of work items that I am attempting to assign to a list of workers. Each working is allowed to only have a max of 100 work items assigned to them. Each work item specifies the user that should work it (associated as an owner).
For example:
Jim works a total of 5 accounts each with multiple work items. In total jim has 50 items to work already assigned to him. I am allowed to assign only 50 more.
My plight/goal:
I am using a temp table and a select statement to get the # of items each owner has currently assigned to them and I calculate the available slots for new items and store the values in new column. I need to be able to select from the items table where the owner matches my list of owners and their available items(in the temp table), only retrieving the number of rows for each user equal to the number of available slots per user - query would return only 50 rows for jim even though there may be 200 matching the criteria while sam may get 0 rows because he has no available slots while there are 30 items for him to work in the items table.
I realize I may be approaching this problem wrong. I want to avoid using a cursor.
Edit: Adding some example code
SELECT
nUserID_Owner
, CASE
WHEN COUNT(c.nWorkID) >= 100 THEN 0
ELSE 100 - COUNT(c.nWorkID)
END
,COUNT(c.nWorkID)
FROM tblAccounts cic
LEFT JOIN tblWorkItems c
ON c.sAccountNumber = cic.sAccountNumber
AND c.nUserID_WorkAssignedTo = cic.nUserID_Owner
AND c.nTeamID_WorkAssignedTo = cic.nTeamID_Owner
WHERE cic.nUserID_Collector IS NOT NULL
AND nUserID_CurrentOwner = 5288
AND c.bCompleted = 0
GROUP BY nUserID_Owner
This provides output vaulues of 5288, 50, 50 (in Jim's scenario)
It took longer than I wanted it to but I found a solution.
I did use a sub-query as suggested above to produce the work items with a unique row count by user.
I used PARTITION BY to produce a unique row count for each worker and included in my HAVING clause that the row number must be < the count of available slots. I'd post the code but it's beyond the char limit and I'd also have a lot of things to change to anon the system properly.
Originally I was approaching the problem incorrectly focusing on limiting the results rather than thinking about creating the necessary data to relate the result sets.

Round up prices to end with 99p

My table name is products and i am trying to update products_price so all prices have 99p at the end. Can you help?
Also this request is a bit simpler (i'm new to SQL!) I want to update all records as follows
anything in categories where parent_id is >0 I need the script to update all records to zero.
Q1
So, you want all prices to be truncated and then add 0.99 currency units. The function to truncate a value to 0 decimal places varies between DBMS; I'm assuming it is called TRUNC, but it might be called FLOOR or something else in your DBMS:
UPDATE Products
SET Products_Price = TRUNC(Products_Price) + 0.99;
You don't need a WHERE clause here. I'm assuming there are no negative prices; if that's a possibility, then you need to be a little cleverer with your assignment (maybe a CASE expression; maybe you have a function SIGN, SIGN, SIGNUM available).
Note that I'm assuming that the p referenced is pence, as in 'pounds (Sterling) and pence'. If the price was between £0.00 and £0.99, the result will be £0.99; if the price was between £1.00 and £1.99, the result will be £1.99; etc. The TRUNC or FLOOR will remove any fractional part from the price, and the addition of 0.99 then means that the result is of the form £x.99 for (non-negative) integer values of x.
Q2
Making some assumptions about what you meant:
UPDATE Categories
SET Anything = 0
WHERE Anything > 0
AND Parent_ID > 0;
If you meant that you want to update the products table in some way, then you need to be a lot more precise in your question.
Q2 revisited
From a comment:
I want to update all parent_id values in my categories table to zero where parent_id > 0.
Presumably, there must be some parent_id values which are null or negative, so you need:
UPDATE Categories
SET Parent_ID = 0
WHERE Parent_ID > 0
If there are no nulls and no negatives, then you can run an even simpler update:
UPDATE Categories
SET Parent_ID = 0
It will set to zero those rows which already have a parent ID of zero as well as those that do not. This might hit the logs a bit harder than the more selective update (as in, there will be more changes to record in the logical log or equivalent for your DBMS), but unless there are vast numbers of records and most of them already have a zero parent ID and the DBMS does not recognize when a record does not change and writes log records for unchanged rows, then you're unlikely to notice the difference
Set price to have 99p at end:
update products_price set price = floor(price)+0.99;
Set parent_id to 0:
update categories set parent_id = 0 where parent_id > 0;