Error in update query - postgresql

I have two entities STOCK(name,amount) and PC_SYSTEMS(name,c_name), and i wish to update the components needed to create the PC_system "Alienware", therefore i want it to subtract 1 from the amount of the components, needed to create the alienware system, in Stock.
Here's my query:
"UPDATE stock SET amount=amount-1 WHERE name = ( SELECT p.c_name FROM pc_systems p WHERE p.name='Alienware');"
I get a weird error that says:
" more than one row returned by a subquery used as an expression"
Would be happy if someone could help.
Edit:
I SOLVED this by putting an "IN" in my query instead of "=". Final code:
UPDATE stock SET amount=amount-1 WHERE name IN ( SELECT p.c_name FROM pc_systems p WHERE p.name='Alienware');

What it means is this SQL returns more than 1 row. Make it so it returns exactly 1 row only.
SELECT p.c_name FROM pc_systems p WHERE p.name='Alienware'

Since your subquery is returning more than one record you cannot use that syntax. try something like this:
UPDATE S
SET S.amount=S.amount-1
FROM Stock S
INNER JOIN pc_systems p
ON S.name = p.c_name
WHERE p.name='Alienware'
or try this:
update stock
set s.amount=s.amount-1
from stock s
inner join pc_systems p on S.name = p.c_name
where p.name='Alienware'

Related

Use postgresql query results to form another query

I am trying to select from one table using the select result from another table. I can run this in two queries but would like to optimize it into just one.
First query.. Select ids where matching other id
select id from lookuptable where paid = '547'
This results in something like this
6316352
6316353
6318409
6318410
6320468
6320469
6320470
6322526
6322527
6324586
6324587
6326648
I would like to then use this result to make another selection. I can do it manually like below. Note, there could be many rows with these values so I've been using a IN statement
select * from "othertable" where id in (6316352,6316353,6318409,6318410,6320468,6320469,6320470,6322526,6322527,6324586,6324587,6326648);
select
ot.*
from
"othertable" as ot
join
lookuptable as lt
on
ot.id = lt.id
where
lt.paid = '547'
The IN operator supports not just value lists but also subqueries, so you can literally write
select * from "othertable" where id in (select id from lookuptable where paid = '547');

How to keep one record in specific column and make other record value 0 in group by clause in PostgreSQL?

I have a set of data like this
The Result should look Like this
My Query
SELECT max(pi.pi_serial) AS proforma_invoice_id,
max(mo.manufacturing_order_master_id) AS manufacturing_order_master_id,
max(pi.amount_in_local_currency) AS sales_value,
FROM proforma_invoice pi
JOIN schema_order_map som ON pi.pi_serial = som.pi_id
LEFT JOIN manufacturing_order_master mo ON som.mo_id = mo.manufacturing_order_master_id
WHERE to_date(pi.proforma_invoice_date, 'DD/MM/YYYY') BETWEEN to_date('01/03/2021', 'DD/MM/YYYY') AND to_date('19/04/2021', 'DD/MM/YYYY')
AND pi.pi_serial in (9221,
9299)
GROUP BY mo.manufacturing_order_master_id,
pi.pi_serial
ORDER BY pi.pi_serial
Option 1: Create a "Running Total" field in Crystal Reports to sum up only one "sales_value" per "proforma_invoice_id".
Option 2: Add a helper column to your Postgresql query like so:
case
when row_number()
over (partition by proforma_invoice_id
order by manufacturing_order_master_id)
= 1
then sales_value
else 0
end
as sales_value
I prepared this SQLFiddle with an example for you (and would of course like to encourage you to do the same for your next db query related question on SO, too :-)

Inner Join subquery in Postgresql results in error

There is my request to find actualities on my website, I got error in this request and I don't know what i need to do for solve this error
Error:
Column "quote_plus_normal_gr_publi.id_post_normal" must appear in the GROUP BY clause or be used in an aggregate fun
Query:
SELECT
publi.date, publi.mess, publi, publi.profil, publi.color,
publi.name, publi.search
FROM
publi
INNER JOIN
(SELECT
id_post_normal, COUNT(id_post_normal)
FROM
quote_plus_normal_gr_publi
ORDER BY
id_post_normal) q ON q.id_post_normal = publi.id_post_normal
WHERE
publi.id_personnes = 1
ORDER BY
date DESC
I think something wrong in your select statement
SELECT publi.date, publi.mess, publi, publi.profil, publi.color, publi.name, publi.search
FROM publi
INNER JOIN (
SELECT id_post_normal, COUNT(id_post_normal)
FROM quote_plus_normal_gr_publi
ORDER BY id_post_normal
) q
ON q.id_post_normal = publi.id_post_normal
WHERE publi.id_personnes = 1
ORDER BY date DESC
in first select there are just publi and don't have column to call
select publi.date, publi.mess, publi, publi.profil
so i try query and make similar to you and i don't have any error to show.
first why the error show up group by? do you try another query? not this query?

oracle: grouping on merged columns

I have a 2 tables FIRST
id,rl_no,adm_date,fees
1,123456,14-11-10,100
2,987654,10-11-12,30
3,4343,14-11-17,20
and SECOND
id,rollno,fare,type
1,123456,20,bs
5,634452,1000,bs
3,123456,900,bs
4,123456,700,bs
My requirement is twofold,
1, i first need to get all columns from both tables with common rl_no. So i used:
SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno
The output is like this:
id,rl_no,adm_date,fees,rollno,fare,type
1,123456,14-11-10,100,123456,20,bs
1,123456,10-11-12,100,123456,900,bs
1,123456,14-11-17,100,123456,700,bs
2,Next i wanted to get the sum(fare) of those rollno that were common between the 2 tables and also whose fare >= fees from FIRST table group by rollno and id.
My query is:
SELECT x.ID,x.rl_no,,x.adm_date,x.fees,x.rollno,x.type,sum(x.fare) as "fare" from (SELECT a.ID,a.rl_no,a.adm_date,a.fees,b.rollno,b.fare,b.type FROM FIRST a
INNER JOIN
SECOND b ON a.rl_no = b.rollno) x, FIRST y
WHERE x.rollno = y.rl_no AND x.fare >= y.fees AND x.type IS NOT NULL GROUP BY x.rollno,x.ID ;
But this is throwing in exceptions.
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
The expected output will be like this:
id,rollno,adm_date,fare,type
1,123456,14-11-10,1620,bs
So could someone care to show an oracle newbie what i'm doing wrong here?
It looks like there's a couple different problems here;
Firstly, you're trying to group by an x.ID column which doesn't exist; it looks like you'll want to add ID to the selected columns in your sub-query.
Secondly, when aggregating with GROUP BY, all selected columns need to be either listed in the GROUP BY statement or aggregated. If you're grouping by rollno and ID, what do you want to have happen to all the extra values for adm_date, fees, and type? Are those always going to be the same for each distinct rollno and ID pair?
If so, simply add them to the GROUP BY statement, ie,
GROUP BY adm_date, fees, type, rollno, ID
If not, you'll need to work out exactly how you want to select which one to be output; If you've got output like your example (adding in an ID column here)
ID,adm_date,fees,rollno,fare,type
1,14-11-10,100,123456,20,bs
1,10-11-12,100,123456,900,bs
1,14-11-17,100,123456,700,bs
Call that result set 'a'. If I run;
SELECT a.ID, a.rollno, SUM(a.fare) as total_fare
FROM a
GROUP BY a.ID, a.rollno
Then the result will be a single row;
ID,rollno,total_fare
1,123456,1620
So, if you also select the adm_date, fees, and type columns, oracle has no idea what you mean to do with them. You're not using them for grouping, and you're not telling oracle how you want to pick which one to use.
You could do something like
SELECT a.ID,
FIRST(a.adm_date) as first_adm_date,
FIRST(a.fees) as first_fees,
a.rollno,
SUM(a.fare) as total_fare,
FIRST(a.type) as first_type
FROM a
GROUP BY a.ID, a.rollno
Which would give the result;
ID,first_adm_date,first_fees,rollno,total_fare,first_type
1,14-11-10,100,123456,1620,bs
I'm not sure if that's what you mean to do though.

Specifice order to tables in postgres

I just created a temporary table as:
create temporary table userAndProductSales as
select p.p_name, u.u_name, u.s_price, u.quantity
from product p
join userAndStates u
on p.s_id = u.s_id
Now I want to select some columns with a particular order. For example, I want the select to give me an output of:
u_name1 p_name1
u_name1 p_name2
u_name1 p_name3
u_name1 p_name4
...
u_name2 p_name1
u_name2 p_name2
u_name2 p_name3
....
and so on and so forth. How do I get this ouput? I've tried something on the lines of:
select (select u_name from userandproductsales order by u_name), p_name from userandproductsales
but I'm getting an error
UPDATE: Figured out that the table I'm joining isn't giving me the correct data I want. Thanks for the help though.
Here is how to use ORDER BY :
SELECT * from userandstatesales
order by u_name , p_name
Unless there is a reason for creating a temporary table (like needing to access it later in the same session), you should avoid the expense and simply do a order by from your select. For example:
select p.p_name, u.u_name, u.s_price, u.quantity
from product p
join userAndStates u
on p.s_id = u.s_id
order by u.u_name, p.p_name;