Select query showing incorrect order in DB2 - db2

While inserting the data in the database third record that is coming is first record at the time of insertion and the first record is second and third one is fourth and so on.
I am using the following query to fetch the data:
SELECT A, B, C, D, E, F FROM MYTABLE WHERE A = 'SOMEPGM' ORDER BY F
F have duplicate records...
why first record becomes third record in the result?

You are doing ORDER BY "MGRSEQ", but there are rows with duplicate MGRSEQ values; you need to specify another column to get a consistent ordering. Ordering without explicit ORDER BY clauses is not guaranteed.

try this:
SELECT "MGRROUT", "MGRTYP", "MGRRRN", "MGRNUM", "MGROPC",
"MGRVAR1", "MGRCOMP", "MGRVAR2", "MGREXC", "MGRSEQ", MGRCAT1
FROM "XPGMLOGIC" WHERE "MGRPGM" = 'BARSCSLMS'
ORDER BY "MGRSEQ", "MGRNUM" DESC

Related

How to update multiple rows using a sub-query and order by in the sub-query?

I am trying to update a table using a sub-query, however the sub-query contains multiple joins as I am getting data from multiple tables, and as a business requirement I am forced to add an Order by in the sub-query to sort elements based on the primary key, if order by is not added then the output is not accurate. A simple example without the joins of what I am trying to do is:
UPDATE EMPLOYEES e
SET (e.JOB, e.SAL, e.COMM) =
(
SELECT p.JOB, p.SAL, p.COMM FROM EMP p WHERE p.ENAME = e.ENAME ORDER BY p.DEPTNO
)
WHERE DEPTNO = 30;
The main issue is not being able to use Order by in sub-query.
This throws an error message:
Error at line 4/80: ORA-00907: missing right parenthesis
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_220100", line 847
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1658
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_220100", line 833
ORA-06512: at "APEX_220100.WWV_FLOW_DYNAMIC_EXEC", line 1903
If I remove the Order by from the sub-query then I get no error message, however my result is not the expected. How can I achieve this?
It is syntactically invalid to have an ORDER BY clause in the outer-most sub-query of a correlated sub-query as the order of the results does not matter as there should only be a single matching row for the sub-query. Therefore the general answer to your question is that it is impossible to have an ORDER BY clause because the syntax forbids it.
Since Oracle 12, there is an exception which allows an ORDER BY clause in a correlated sub-query and that is when you also use FETCH FIRST ROW ONLY to guarantee that the sub-query returns only a single row.
So, if you are getting multiple rows for the sub-query and you only want the first row then, from Oracle 12, you can use:
UPDATE EMPLOYEES e
SET (e.JOB, e.SAL, e.COMM) = (SELECT p.JOB, p.SAL, p.COMM
FROM EMP p
WHERE p.ENAME = e.ENAME
ORDER BY p.DEPTNO
FETCH FIRST ROW ONLY)
WHERE DEPTNO = 30;
However, it seems more likely that you would want to use something else to correlate the queries so that you only ever get a single row.
as a business requirement I am forced to add an Order by in the sub-query to sort elements based on the primary key
This does not appear to be what you are doing as you are sorting by the department number, DEPTNO, and it seems to be unlikely that the primary key for an employee is the number of their department.
db<>fiddle here

Is distinct function deterministic? T-sql

I have table like below. For distinct combination of user ID and Product ID SQL will select product bought from store ID 1 or 2? Is it determinictic?
My code
SELECT (DISTINCT CONCAT(UserID, ProductID)), Date, StoreID FROM X
This isn't valid syntax. You can have
select [column_list] from X
or you can have
select distinct [column_list] from X
The difference is that the first will return one row for every row in the table while the second will return one row for every unique combination of the column values in your column list.
Adding "distinct" to a statement will reliably produce the same results every time unless the underlying data changes, so in this sense, "distinct" is deterministic. However, it is not a function so the term "deterministic" doesn't really apply.
You may actually want a "group by" clause like the following (in which case you have to actually specify how you want the engine to pick values for columns not in your group):
select
concat(UserId, ProductID)
, min(Date)
, max(Store)
from
x
group by
concat(UserId, ProductID)
Results:
results

Update statement where one column depends on another updated column

I want to update two columns in my table, one of them depends on the calculation of another updated column. The calculation is rather complex, so I don't want to repeat that every time, I just want to use the newly updated value.
CREATE TABLE test (
A int,
B int,
C int,
D int
)
INSERT INTO test VALUES (0, 0, 5, 10)
UPDATE test
SET
B = C*D * 100,
A = B / 100
So my question, is this even possible to get 50 as the value for column A in just one query?
Another option would be to use persistent computed columns, but will that work when I have dependencies on another computed column?
you cant achieve what you are trying to in a single query.This is due to a Concept called All At Once Operations which translates to "In SQL Server, Operations which appears in Same logical Phase are evaluated at the same time.."..
Below operations wont yield result you are expecting
insert into table1
(t1,t1+100,t1+200)-- sql wont use new t1 incremented value
sames goes with update as well
update t1
set t1=t1*100
t2=t1 --sql wont use t1 updated value(*100)
References:
TSQL Querying by Itzik Ben-Gan

Issue with the count in PostgreSQL

I want the count of the one column and I have 5 columns in FROM clause but it is giving wrong count as I have included all my columns that are in the from clause. I don't want that particular column in the GROUP BY clause.
If I remove that column from GROUP BY clause it throws the following error:
ERROR: column "pt.name" must appear in the GROUP BY clause or be used
in an aggregate function LINE 1: SELECT distinct on (pu.id) pu.id,
pt.name as package_name, c...
E.g.:
SELECT DISTINCT ON (a) a,b,c,count(d),e
FROM table GROUP BY a,b,c,d,e ORDER BY a
From this I want to remove e from the GROUP BY.
How can I remove that column from GROUP BY so that I can get correct count?
Updated after rereading the question.
You are mixing GROUP BY and DISTINCT ON. What you want (how I understand it) can be done with a window function combined with a DISTINCT ON:
SELECT DISTINCT ON (a)
a, b, c
, count(d) OVER (PARTITION BY a, b, c) AS d_ct
, e
FROM tbl
ORDER BY a, d_ct DESC;
Window functions require PostgreSQL 8.4 ore later.
What happens here?
Count in d_ct how many identical sets of (a,b,c) there are in the table with non-null values for d.
Pick exactly one row per a. If you don't ORDER BY more than just a, a random row will be picked.
In my example I ORDER BY d_ct DESC in addition, so a pseudo-random row out of the set with the highest d_ct will be picked.
Another, slightly different interpretation of what you might need, with GROUP BY:
SELECT DISTINCT ON (a)
a, b, c
, count(d) AS d_ct
, min(e) AS min_e -- aggregate e in some way
FROM t
GROUP BY a, b, c
ORDER BY a, d_ct DESC;
GROUP BY is applied before DISTINCT ON, so the result is very similar to the one above, only the value for e / min_e is different.

TSQL selecting unique value from multiple ranges in a column

A question from a beginner.
I have two tables. One (A) contains Start_time, End_time, Status. Second one (B) contains Timestamp, Error_code. Second table is automatically logged by system every few seconds, so it contains lots of non unique values of Error_code (it changes randomly, but within a time range from table A). What i need is to select unique error code for every time range (in my case every row) from the first table for every time range in table A:
A.Start_time, A.End_time B.Error_code.
I have come to this:
select A.Start_time,
A.End_time,
B.Error_code
from B
inner join A
on B.Timestamp between A.Start_time and A.End_time
This is wrong, i know.
Any thoughts are welcome.
If tour query gives a lot of duplicates use distinct to remove them:
select DISTINCT A.Start_time, A.End_time, B.Error_code
from B
inner join A on B.Timestamp between A.Start_time and A.End_time