This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Closed 4 years ago.
I have a table named 'versions' which has columns control_no, revision_id ,revision_dt, version_no, version_dt, created_by, change_type, summary, new_owner.
Each control_no has revision_id ranging from 1 to a specific number. From this table, I want to select
VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_BY for a CONTROL_NO with max(REVISION_ID).
How to do this?
Use the below query
select VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_BY from VERSIONS where REVISION_ID in (SELECT A.REVISION_LIST FROM (select max(REVISION_ID) AS REVISION_LIST, CONTROL_NO AS CONT_NO from VERSIONS GROUP BY CONTROL_NO)A);
this will work:
select VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_BY,max(REVISION_ID),control_no
from versions group by control_no;
By Below Code you can get
SELECT MAX(Version_id) AS Version_id, VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_By, CONTROL_NO
from table
GROUP BY VERSION_NO,CHANGE_TYPE,SUMMARY,CREATED_By, CONTROL_NO
Related
This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 6 months ago.
This is the query in one of the Reports that I am trying to fix. What is being done here?
select
*
from
(
SELECT
[dbo].[RegistrationHistory].[AccountNumber],
[dbo].[RegistrationHistory].[LinkedBP],
[dbo].[RegistrationHistory].[SerialNumber],
[dbo].[RegistrationHistory].[StockCode],
[dbo].[RegistrationHistory].[RegistrationDate],
[dbo].[RegistrationHistory].[CoverExpiry],
[dbo].[RegistrationHistory].[LoggedDate] as 'CoverExpiryNew',
ROW_NUMBER() OVER(PARTITION BY [dbo].[RegistrationHistory].[SerialNumber]
ORDER BY
LoggedDate asc) AS seq,
[dbo].[Registration].[StockCode] as 'CurrentStockCode'
FROM
[SID_Repl].[dbo].[RegistrationHistory]
LEFT JOIN
[SID_Repl].[dbo].[Registration]
on [dbo].[RegistrationHistory].[SerialNumber] = [dbo].[Registration].[SerialNumber]
where
[dbo].[RegistrationHistory].[StockCode] in
(
'E4272HL1',
'E4272HL2',
'E4272HL3',
'E4272H3',
'OP45200HA',
'OP45200HM',
'EOP45200HA',
'EOP45200HM',
'4272HL1',
'4272HL2',
'4272HL3',
'4272H3'
)
)
as t
where
t.seq = 1
and CurrentStockCode in
(
'E4272HL1',
'E4272HL2',
'E4272HL3',
'E4272H3',
'OP45200HA',
'OP45200HM',
'EOP45200HA',
'EOP45200HM',
'4272HL1',
'4272HL2',
'4272HL3',
'4272H3'
)
I am looking for a simplified way of splitting this query into step by step, so that I can see where it is going wrong.
ROW_NUMBER in a subquery combined with a filter on it in the outer query is an idiom to filter out all but the first row in a group. So here
ROW_NUMBER() OVER(PARTITION BY [dbo].[RegistrationHistory].[SerialNumber])
Assigns the row with the lowest SerialNumber 1, the next lowest, 2, etc. Then later
where
t.seq = 1
removes all but the row with the lowest serial number from the result.
This question already has answers here:
Display default value if query results in no records in BigQuery
(2 answers)
Closed 10 months ago.
My question is I want to get null values when there is "no data to display" in the BigQuery.
like this:
But it only works when there are only aggregate functions. How to modify below query so that returns null values?
My query:
select oid, date, coalesce(sum(quantity_sold),0) as quantity_sold
from table
where oid = 'xxx' and (date >= 'xxx' and date <= 'xxx')
group by 1,2
I found this similar SO question but it creates a column that contains a message that says "Results not found" and assigns null values to other columns. You can apply this query and remove the message and retain only the null values, your query will look like this:
with sample_data as (
select 123 as oid, '2022-01-01' as date, 23 as quantity_sold
union all select 111 as oid, '2022-01-02' as date, 24 as quantity_sold
),
actual_query as (
select oid,date,coalesce(sum(quantity_sold),0) as quantity_sold
from sample_data
where oid = 534 and (date >= '2021-03-23' and date <= '2021-04-23')
group by 1,2
)
-- query below is the modified query from the linked SO question above
select actual_query.*
from actual_query
union all
select actual_query.* -- all the `actual_query` columns will be `NULL`
from (select 1) left join
actual_query
on 1 = 0 -- always false
where not exists (select 1 from actual_query);
Sample output:
NOTE: I created random values for sample data that could mimic the message "There is no data to display" when I ran your query.
This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Select First Row of Every Group in sql [duplicate]
(2 answers)
Return row with the max value of one column per group [duplicate]
(3 answers)
Get value based on max of a different column grouped by another column [duplicate]
(1 answer)
SQL: getting the max value of one column and the corresponding other columns [duplicate]
(2 answers)
Closed 2 years ago.
I have a table called ro_main_table which stores details of productions such as serial_nr, pr_date_time, machine_nr, record_key etc. I would like to get the distinct machine_nr and record key from ro_main_table where pr_date_time is in last 6 hours. For this I do:
select machine_nr, record_key, pr_date_time from ro_main_table where pr_date_time >= SYSDATE - 6/24;
Which gives me the table below:
MACHINE_NR
RECORD_KEY
PR_DATE_TIME
54
9809
17-DEC-20 04.02.35.000000000 AM
55
9811
17-DEC-20 04.58.22.000000000 AM
55
9817
17-DEC-20 09.17.50.000000000 AM
54
9814
17-DEC-20 07.57.24.000000000 AM
50
9818
17-DEC-20 09.45.22.000000000 AM
However, as you see there might be machines which are started twice during this time (i.e. machine_nr occurs multiple times). If this is the case, I will choose the record which has the highest record_key. For example, for machine 55 it is 9817. How can I achieve this?
Thank you very much in advance!
select machine_nr, max(record_key), pr_date_time
from ro_main_table
where pr_date_time >= SYSDATE - 6/24
group by machine_nr;
this query should get the result you wish
I found a way. I create an inner join like this:
select tt.machine_nr, tt.record_key, tt.pr_date_time
from ro_main_table tt
INNER JOIN
(SELECT machine_nr, MAX(record_key) AS MaxRecordKey
FROM ro_main_table
GROUP BY machine_nr) groupedtt
ON tt.machine_nr = groupedtt.machine_nr
AND tt.record_key = groupedtt.MaxRecordKey
where pr_date_time >= SYSDATE - 6/24;
You can use the window function as follows:
select * from
(select machine_nr, record_key, pr_date_time
row_number() over (partition by machine_nr order by record_key desc) as rn
from ro_main_table where pr_date_time >= SYSDATE - 6/24)
where rn = 1;
This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
GROUP BY with MAX(DATE) [duplicate]
(6 answers)
Oracle SQL query: Retrieve latest values per group based on time [duplicate]
(2 answers)
Closed 5 years ago.
It's been marked as a duplicate and seems to be explained a bit in the linked questions, but I'm still trying to get the separate DEBIT and CREDIT columns on the same row.
I've created a View and I am currently self joining it. I'm trying to get the max Header_ID for each date.
My SQL is currently:
SELECT DISTINCT
TAB1.id,
TAB1.glperiods_id,
MAX(TAB2.HEADER_ID),
TAB1.batch_date,
TAB1.debit,
TAB2.credit,
TAB1.descrip
FROM
IQMS.V_TEST_GLBATCH_GJ TAB1
LEFT OUTER JOIN
IQMS.V_TEST_GLBATCH_GJ TAB2
ON
TAB1.ID = TAB2.ID AND TAB1.BATCH_DATE = TAB2.BATCH_DATE AND TAB1.GLPERIODS_ID = TAB2.GLPERIODS_ID AND TAB1.DESCRIP = TAB2.DESCRIP AND TAB1.DEBIT <> TAB2.CREDIT
WHERE
TAB1.ACCT = '3648-00-0'
AND
TAB1.DESCRIP NOT LIKE '%INV%'
AND TAB1.DEBIT IS NOT NULL
GROUP BY
TAB1.id,
TAB1.glperiods_id,
TAB1.batch_date,
TAB1.debit,
TAB2.credit,
TAB1.descrip
ORDER BY TAB1.batch_date
And the output for this is (37 rows in total):
I'm joining the table onto itself to get DEBIT and CREDIT on the same line. How do I select only the rows with the max HEADER_ID per BATCH_DATE ?
Update
For #sagi
Those highlighted with the red box are the rows I want and the ones in blue would be the ones I'm filtering out.
Fixed mistake
I recently noticed I had joined my table onto itself without making sure TAB2 ACCT='3648-00-0'.
The corrected SQL is here:
SELECT DISTINCT
TAB1.id,
TAB1.glperiods_id,
Tab1.HEADER_ID,
TAB1.batch_date,
TAB1.debit,
TAB2.credit,
TAB1.descrip
FROM
IQMS.V_TEST_GLBATCH_GJ TAB1
LEFT OUTER JOIN
IQMS.V_TEST_GLBATCH_GJ TAB2
ON
TAB1.ID = TAB2.ID AND TAB1.BATCH_DATE = TAB2.BATCH_DATE AND TAB2.ACCT ='3648-00-0'AND TAB1.GLPERIODS_ID = TAB2.GLPERIODS_ID AND TAB1.DESCRIP = TAB2.DESCRIP AND TAB1.DEBIT <> TAB2.CREDIT
WHERE
TAB1.ACCT = '3648-00-0'
AND
TAB1.DESCRIP NOT LIKE '%INV%'
AND TAB1.DEBIT IS NOT NULL
ORDER BY TAB1.BATCH_DATE
Use window function like ROW_NUMBER() :
SELECT s.* FROM (
SELECT t.*,
ROW_NUMBER() OVER(PARTITION BY t.batch_id ORDER BY t.header_id DESC) as rnk
FROM YourTable t
WHERE t.ACCT = '3648-00-0'
AND t.DESCRIP NOT LIKE '%INV%'
AND t.DEBIT IS NOT NULL) s
WHERE s.rnk = 1
This is an analytic function that rank your record by the values provided in the OVER clause.
PARTITION - is the group
ORDER BY - Who's the first of this group (first gets 1, second 2, ETC)
It is a lot more efficient then joins(Your problem could have been solved in many ways) , and uses the table only once.
This question already has answers here:
How to find rows in one table that have no corresponding row in another table
(6 answers)
Closed 9 years ago.
I'm trying to get rows from tblReqInfo when ReqID is between 5 and 8 and there is NO corresponding row in tblSomeTable
SELECT *
FROM tblReqInfo
WHERE (RI_ReqID BETWEEN 5 AND 8)
AND
CASE
WHEN NOT EXISTS
(SELECT CC_ReqID
FROM tblSomeTable
WHERE (CC_UserID = #CC_UserID) )
THEN 1
ELSE RI_ReqID NOT IN (SELECT CC_ReqID
FROM tblSomeTable
WHERE (CC_UserID = #CC_UserID) )
END
ORDER BY RI_ReqID
Unfortunately, the query configuration wizard can't even parse this. Can anyone discern what query might work for me?
Try this in SQL Server:
SELECT *
FROM tblReqInfo
WHERE (RI_ReqID BETWEEN 5 AND 8)
AND RI_ReqID NOT IN
(SELECT CC_ReqID
FROM tblSomeTable
WHERE CC_UserID = #CC_UserID)
The standard solution to this problem is to perform an outer join from the target table to the referent table and then grab the rows where there is no match in the referent:
SELECT target.*, referent.id
FROM target LEFT OUTER JOIN
referent ON (target.id = referent.id)
WHERE target.id BETWEEN 5 and 8
AND referent.id IS null
ORDER BY target.id