more than one row returned by a subquery used as an expression problem - postgresql

I am trying to update a column in one database with a query:
Here the query
and this is the output i think it is impossible to asign a query to a field but what is the solution for that plz.
enter image description here

= can be used when we are pretty sure that the subquery returns only 1 value.
When we are not sure whether subquery returns more than 1 value, we will have to use IN to accommodate all values or simply use TOP 1 to limit the equality matching to one value:
UPDATE mascir_fiche SET partner = (SELECT TOP 1 id FROM hr_employee WHERE parent_id IN (SELECT id FROM hr_employee));
With Limit:
UPDATE mascir_fiche SET artner = (SELECT id FROM hr_employee WHERE parent_id IN (SELECT id FROM hr_employee) limit 1);

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');

Single Value Expression in When Then Aggregate Function TSQL

I am trying to map a certain value of a column based on its count on another table. If the count of [Location] i.e a column of IMPORT.DATA_SCRAP table in each row. For now for location static value i.e Utah and Kathmandu is supplied for test purpose only is equal to 1, then only i need to get the result in the select statement i.e only single value expression must be returned but here n rows of table with value is returned.
For. eg. In the below query,total rows of IMPORT.DATA_SCRAP gets returned, i only need the single first row value in my case.
I came to know whether cursor or CTE will acheive my result but i am unable to figure it out.
Here,
select
case
when
((SELECT COUNT(stateName) FROM Location.tblState where stateName = 'Utah')=1)
then (select stateName, CountryName from Location.tblState where stateName= 'Utah')
end as nameof
from IMPORT.DATA_SCRAP
The relation between country, state, city is as below:
select
case
when
((SELECT COUNT(cityName) FROM Location.tblCity where cityName = 'Kathmandu')=1)
then (select ct.countryName from Location.tblCity c
inner join Location.tblState s
on c.stateID = s.StateID
inner join Location.tblCountry ct
on ct.countryId = s.CountryId
where c.cityName = 'Kathmandu'
)
end as nameof
from IMPORT.DATA_SCRAP
How can i return only a single value expresion despite of multiple nmax rows of IMPORT.DATA_SCRAP row in the result.
If i comment out the -- from IMPORT.DATA_SCRAP in the above query i would get the desired single result expression in my case, but unable how can i acheive it in other ways or suggest me the appropriate way to do these types of situation.

Get Max value of a DATE and an ID in order to filter results

I'm trying to get the latest "date" so the max value of "date" and from the same table I want the max value of "stand" also from the same ID.
I have tons of dates, stands for one ID but i only want to extract the latest.
im trying to save it into a function i dont know yet if thats the best idea. The rest of my query It's made of inner joins.
Datum is of type date.
stand is decimal(18,6)
DECLARE #MAXDATE DATE
DECLARE #MAXSTAND decimal(18,6)
SELECT #MAXDATE = MAX(Datum) FROM [dbo].[1] WHERE ID = ID
SELECT #MAXSTAND = Stand FROM [dbo].[2]WHERE ID = ID
Result I get: #MAXDATE: 2106-10-13
Result I get: #MAXSTAND: 0.000000
Result I want: #MAXDATE: 2018-01-16
result I want: #MAXSTAND: 1098.000000
Assuming SQL Server 2012 or higher, you can use the first_value window function:
SELECT FIRST_VALUE(Stand) OVER(ORDER BY Datum DESC)
FROM TableName
WHERE Id = #Id
This will return the value of Stand where the Datum column has the latest value for the specific Id.
With the data provided, I don't think you need to do something else :
SELECT MAX(Datum), MAX(Stand)
FROM TableName
WHERE ID = #MyId
edit : You want it by ID, you can do this :
SELECT MAX(Datum), MAX(Stand), ID
FROM TableName
GROUP BY ID

excluding rows from resultset in postgres

This is my result set
i am returning this result set on the base of refid using WHERE refid IN.
Over here, i need to apply a logic without any kind of programming (means SQL query only).
if in result set, i am getting period for particular refid then other rows with the same refid must not returned.
for example, 2667105 having period then myid = 612084598 must not get returned in result set.
according to me this can be achieved using CASE but i have no idea how to use it, i mean that i don't know should i use the CASE statement in SELECT statement or WHERE clause...
EDIT:
This is how it suppose to work,
myid = 612084598 is the default row for refid = 2667105 but if specifically wants the refid for period = 6 then it must return all rows except myid = 612084598
but if i am looking for period = 12, for this period no specific refid present in database.. so for this it must return all rows except first one.. means all rows with the refid which is default one..
Not very clear definition of the problem, but try this:
with cte as (
select
*,
first_value(period) over(partition by refid order by myid) as fv
from test
)
select
myid, refid, period
from cte
where period is not null or fv is null
sql fiddle demo

PostgreSQL and pl/pgsql SYNTAX to update fields based on SELECT and FUNCTION (while loop, DISTINCT COUNT)

I have a large database, that I want to do some logic to update new fields.
The primary key is id for the table harvard_assignees
The LOGIC GOES LIKE THIS
Select all of the records based on id
For each record (WHILE), if (state is NOT NULL && country is NULL), update country_out = "US" ELSE update country_out=country
I see step 1 as a PostgreSQL query and step 2 as a function. Just trying to figure out the easiest way to implement natively with the exact syntax.
====
The second function is a little more interesting, requiring (I believe) DISTINCT:
Find all DISTINCT foreign_keys (a bivariate key of pat_type,patent)
Count Records that contain that value (e.g., n=3 records have fkey "D","388585")
Update those 3 records to identify percent as 1/n (e.g., UPDATE 3 records, set percent = 1/3)
For the first one:
UPDATE
harvard_assignees
SET
country_out = (CASE
WHEN (state is NOT NULL AND country is NULL) THEN 'US'
ELSE country
END);
At first it had condition "id = ..." but I removed that because I believe you actually want to update all records.
And for the second one:
UPDATE
example_table
SET
percent = (SELECT 1/cnt FROM (SELECT count(*) AS cnt FROM example_table AS x WHERE x.fn_key_1 = example_table.fn_key_1 AND x.fn_key_2 = example_table.fn_key_2) AS tmp WHERE cnt > 0)
That one will be kind of slow though.
I'm thinking on a solution based on window functions, you may want to explore those too.