Update table setting the value of a field to the result of a query - sql

I have the following table(let's call it Sales) structure:
What I would like to do is to fill the field "SalesID" with values resulting from a query I have created in the same DB. This query reflects the table structure so I was thinking to connect the two using the ID.
Basically, I am trying with scripts of this forms:
UPDATE Sales
SET SalesID = ( SELECT SalesIDCalc FROM (SELECT Sales.ID, Sales.[Email Address], Sales.[Points], IIf([Points] >80,"Super","Normal") AS SalesIDCalc FROM Sales) AS q
WHERE Sales.ID = q.ID);
but I am nowhere near the solution. Do you have any idea on how to proceed?
EDIT: Now I get the Error 'Operation must use an updateable table'

I think you want UPDATE with a correlated subquery:
UPDATE Sales
SET SalesID = (SELECT SalesIDCalc
FROM (MyQuery) as q
WHERE Sales.ID = q.ID
);

Related

Reduce the oracle PL/SQL statement

I am a new in PL/SQL. After hours of learning, I have some
I have a few curious questions. Example I have a SQL statement like this:
SELECT ShipperName, OrderID, NumberOfOrders, ...
FROM Orders
Can we declare a variable that hold the "list select" like list_select = 'ShipperName, OrderID, NumberOfOrders, ... '
And then replace the select statement with the "list select" we was declared?
SELECT list_select
FROM Orders
And other question, Can we reduce the SQL statement like the Image . I was try this in Oracle SQL Developer, the compiler is ok but when I ran the test I was got an error "by segment".
Any help is appreciated and thank for help.
For your first question, You may search for "EXECUTE IMMEDIATE" statement which is used for dynamic query execution. So you may try something like below -
EXECUTE IMMEDIATE 'SELECT ' || YOUR_COMMA_DELIMITED_COLUMNS_LIST || ' FROM Orders';
For 2nd, Please post the sample data and expected result.
For your second question: You don't want joins here, because you only select from table1. You rather want [NOT] EXISTS or [NOT] IN. E.g.:
SELECT orderid, clientid
FROM orders o
WHERE EXISTS -- We are looking for orders containing expensive items
(
SELECT null
FROM orderposition op
WHERE op.orderid = o.orderid
AND op.price > 1000
)
AND -- and the client ...
(
NOT EXISTS -- ... must have paid all their invoices (there exists no unpaid invoice)
(
SELECT null
FROM invoices i
WHERE i.clientid = o.clientid
AND i.paid_date IS NULL
)
OR clientid IN -- ... or be known as reliable client (they are in the set of reliable ones)
(
SELECT c.clientid
FROM clients c
WHERE c.reliable = 'YES'
)
);

Update largest date, matching two fields

tables
Hi, I'm looking to update the last column in a blank table. Picture shows input and desired output. Trying to pick the largest date where workorder and state match.
I've tried a couple different codes:
UPDATE mytable
SET mytable.orderstartdate = MAX(table2.earliestdate)
FROM mytable as table2
WHERE (mytable.workorder = table2.workorder AND
mytable.state = table2.state)
;
"Syntax Error (missing operator) in query expression 'MAX(table2.earliestdate) FROM mytable as table2'."
UPDATE mytable
SET mytable.orderstartdate = (
SELECT max(earliestdate)
FROM mytable as table2
WHERE (mytable.workorder = table2.workorder AND
mytable.state = table2.state)
)
;
"Operation must use an updateable query"
Edit - click tables link for image.
Write PL/SQL Code.
First, select DISTINCT WorkOrder and State and capture in variables.
Now, Iterate the list and Write a query to get max date i.e. max(date) using work_order and State in where clause. Capture the
date.
Now, In the same loop write update query setting max(date) and workorder and State in where clause.
UPDATE table A
SET A.orderstartDate = (SELECT max(earliestdate)
FROM table B
WHERE A.WorkOrder = B.WorkOrder
GROUP BY WorkOrder)
not sure if access supports correlated subqueries but if it does...
and if not...
UPDATE table A
INNER JOIN (SELECT WorkOrder, max(OrderStartDate) MOSD
FROM Table B
GROUP BY WorkOrder) C
ON A.WorkOrder = C.workOrder
SET A.OrderStartDate = C.MOSD
Check database open mode, it may be locked for editing, or you may have no permission to to file.

Opencart - phpMyAdmin Bulk update Special Price

I work as administrator in one electronic shop we are using OpenCart eCommerce and recently they asked me to add special price to Bulk products and leave it running for some days. Of course i can change it in admin page one by one. The things is how i can change it through phpMyAdmin.
( Opencart Version 2.1.0.1 )
I have 46 products which cost 25€ and i have to add special price to 20€.
Table we have to update price is
oc_product_special
and column we have to update is
oc_product_special.price
Of course we need products which cost 25€ from table
oc_product
to retrieve products from this table and add special price to 20€
The thing is how to connect these two tables so i can add special price which sql query to run so i can achieve this.
oc_product & oc_product_special , update this column oc_product_special.price
I 've tried to run this sql query but i receive error
UPDATE `oc_product_special`.price
SET `oc_product_special`.price = 16.1290
FROM `oc_product`
INNER JOIN `oc_product_special`
ON `oc_product`.product_id =`oc_product_special`.product_id
WHERE`oc_product`.price = 20.1612;
**** Price is without taxes 25€ / 1,24(tax rate) = 20.1612€
Error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM oc_product INNER JOIN oc_product_special ON oc_product.product_id =' at line 2
Any help is appreciated
** EDIT
Updating my Sql query
UPDATE oc_product_special AS ps
INNER JOIN oc_product op ON ps.product_id = op.product_id
set ps.price = 16.1290
where op.price = 20.1612
but the thing is that 0 rows affected. (Query took 0.0003 sec) , if i run select query with these prices i have results.
select *
from oc_product as op
where op.price=20.1612
Showing rows 0 - 29 (46 total, Query took 0.0010 sec)
***** Updated 2nd time
Firstly i ran
DELETE FROM `oc_product_special`
WHERE product_id IN
(
SELECT product_id
FROM oc_product p
WHERE p.price = 20.1612
);
so i can " remove any existing specials from these products " , this query ran without any issue
After that i tried to ran Insert query
INSERT INTO `oc_product_special` (`product_special_id`, `product_id`, `customer_group_id`, `priority`, `price`, `date_start`,`date_end`)
VALUES
(
SELECT NULL, 78, 1, 0, 16.1290, 0000-00-00, 0000-00-00
FROM oc_product p
WHERE p.price = 20.1612
);
I adjusted my data concerning to my table's data. But i receive this error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT NULL, 78, 1, 0, 16.1290, 0000-00-00, 0000-00-00 FROM oc_product p ' at line 4
Your query has no formatting and does not correspond to MySQL standards, you have to pay attention to the following:
After an UPDATE statement one should specify the table to use and not the column
The SET statement only comes after an INNER JOIN
Use suffixes for convenience when joining tables
Correct MySQL query below (change the prices):
UPDATE oc_product_special AS ps
INNER JOIN oc_product op ON ps.product_id = op.product_id
set ps.price = 22 where op.price = 0.00
You need an insert statement rather than an update. You might also consider removing any existing specials from these products beforehand and run a query to clear them like this:
DELETE FROM `oc_product_special`
WHERE product_id IN
(
SELECT product_id
FROM oc_product p
WHERE p.price = 20.1612
);
Then you can select the desired product ids along with other fields and insert them like this:
INSERT INTO `oc_product_special` (`product_special_id`, `product_id`, `customer_group_id`, `priority`, `price`, `date_start`, `date_end`)
VALUES
(
SELECT NULL, product_id, 1, 0, 16.1290, CURDATE(), CURDATE() + INTERVAL 1 DAY
FROM oc_product p
WHERE p.price = 20.1612
);
In this example the special starts today and runs for 5 days. Of course you should adjust the customer_group_id, priority,start_date, andend_date` in my query.

alternatives to using IN clause

I am running the below query:
SELECT
ReceiptVoucherId,
VoucherId,
ReceiptId,
rvtransactionAmount,
AmountUsed,
TransactionTypeId
FROM
[Scratch].[dbo].[LoyaltyVoucherTransactionDetails]
WHERE
VoucherId IN
(2000723,
2000738,
2000774,
2000873,
2000888,
2000924,
2001023,
2001038,
2001074,
2001173)
the aim being to extract the ReceiptVoucherId / VoucherId / ReceiptId / rvtransactionAmount / AmountUsed / TransactionTypeId data for the list of voucherId's that I have.
My problem here is that my list of VoucherID's is 187k long so an IN clause is not possible as it returns the error:
Internal error: An expression services limit has been reached
Can anyone advise on a alternative to doing it this way?
I am using SSMS 2014
You can try the approach:
select from mytable where id in (select id from othertable)
or left join:
select from othertable left join mytable using id
not sure what has better performance, also second query could give you empty rows if it is not declared as foreign key.
fly-by-post, feel free to improve it.
Just create a table containing all this Vouchers (Hopefully you already have one) and then use IN() selecting from the table :
SELECT
ReceiptVoucherId,
VoucherId,
ReceiptId,
rvtransactionAmount,
AmountUsed,
TransactionTypeId
FROM
[Scratch].[dbo].[LoyaltyVoucherTransactionDetails]
WHERE
VoucherId IN (SELECT VoucherId FROM VourchersTable)
insert the vouchers to lookup in a seperate table . lets call it Voucher.
Then this query should do the trick. It does not use the IN Clause. but instead it uses Inner join which will be faster.
SELECT
L.ReceiptVoucherId,
L.VoucherId,
L.ReceiptId,
L.rvtransactionAmount,
L.AmountUsed,
L.TransactionTypeId
FROM
[Scratch].[dbo].[LoyaltyVoucherTransactionDetails] L
INNER JOIN dbo.Vouchers V ON L.VoucherId = V.VoucherId
Maybe the following works for you:
First of all, declare a variable of type table (or alternatively a temp table) and insert your IDs into it.
Modify your Query to
WHERE VoucherID in (SELECT VoucherID FROM #t)
Alternatively (but similar write-intensive for your Hands ;-) ) is the creation of a CTE:
WITH cte AS (SELECT 2000723 UNION ALL SELECT ...)
and again the redesign of your "WHERE... IN..." section.

Can you run an UPDATE and WITH together?

I am trying to run an update on a table, but get an error
ERROR: syntax error at or near "UPDATE"
The query is:
WITH
first_users AS (
select min(created_at) as first_at,
company_id as company_id
from users
group by company_id
)
UPDATE companies
SET first_seen_at = LEAST(first_seen_at,
(SELECT first_at FROM first_users WHERE id = first_users.company_id)
);
Can you not run UPDATEs and WITHs together? Seems weird.
My query is actually slightly more complex, which is why I am using the with syntax. When I run SELECT * FROM first_users instead of UPDATE, it works, so there's something wrong with the UPDATE keyword or something.
I would suggest changing this to an update . . . from in any case. There is no reason to update records that do not match. So:
update companies
set first_seen_at = u.first_at
from (select company_id, min(created_at) as first_at
from users
group by company_id
) u
where companies.id = u.company_id and
u.first_seen_at < companies.first_seen_at;
Postgres started supporting CTEs with updates in version 9.1 (http://www.postgresql.org/docs/9.1/static/sql-update.html vs http://www.postgresql.org/docs/9.0/static/sql-update.html). This method is better because it filters the rows before the update.
Try encapsulating the query qith BEGIN/END. I don't know about PostgreSql, but MsSql does not accept WITH without BEGIN/END...