This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 11 months ago.
SELECT
ASTRO_VIEW_CNT_O08.pickdate, -- picking day;
ASTRO_VIEW_CNT_O08.linestat, -- picking line status;
ASTRO_VIEW_CNT_O08.partno, -- product name
ASTRO_VIEW_CNT_O08.reqquant, -- orderd quantity
ASTRO_VIEW_CNT_O08.delquant,-- delivered quantity
ASTRO_VIEW_CNT_O08.ordno,--- order number
L16T3.fmha -- from material handling area
FROM ASTRO_VIEW_CNT_O08 - VIEW TABLE FROM ORDERS
LEFT JOIN L16T3 ON ASTRO_VIEW_CNT_O08.shorto08=L16T3.shorto08 --- L16T3 is Logg table with history data
WHERE linestat IN (0,7,25) AND delquant=0
ORDER BY reqquant DESC
I get double results.
For example:
<07.03.2022, 25, 31012 , 640 0, SH1, 777011;>
<07.03.2022, 25, 31012 , 640 0, , 777011;>
`07.03.2022, 25, 31012 , 640 0, DP14, 777011;`
`07.03.2022, 25, 31012 , 640 0, SH1OT,777011;`
`07.03.2022, 25, 31012, 640 0, UT121,777011;`
I want to take only one row from order number (777011).
For a same material handling area there are different ASTRO_VIEW_CNT_O08.ordno due to which you are getting duplicate/more number of records. Try removing the ASTRO_VIEW_CNT_O08.ordno in the select.
Or you can try as below.
;with FinalOutput as
(SELECT
ASTRO_VIEW_CNT_O08.pickdate, -- picking day;
ASTRO_VIEW_CNT_O08.linestat, -- picking line;
ASTRO_VIEW_CNT_O08.partno, -- product name
ASTRO_VIEW_CNT_O08.reqquant, -- orderd quantity
ASTRO_VIEW_CNT_O08.delquant,-- delivered quantity
ASTRO_VIEW_CNT_O08.ordno,--- order number
L16T3.fmha, -- from material handling area,
row_number() over (partition by L16T3.fmha order by L16T3.fmha) as rownum
FROM ASTRO_VIEW_CNT_O08 - VIEW TABLE FROM ORDERS
LEFT JOIN L16T3 ON ASTRO_VIEW_CNT_O08.shorto08=L16T3.shorto08 --- L16T3 is Logg table with history data
WHERE linestat IN (0,7,25) AND delquant=0
)
select * from FinalOutput
where rownum=1
ORDER BY reqquant DESC
Related
I want to update 15 records in that first 5 records date should be June 2019,next 5 records with July 2019,last 5 records with Aug 2019 based on employee id,Can any one tell me how to write this type of query in SQL Server Management Studio V 17.7,I've tried with below query but unable to do for next 5 rows..
Like below query
Update TOP(5) emp.employee(nolock) set statusDate=GETDATE()-31 where EMPLOYEEID='XCXXXXXX';
To update only a certain number of rows of a table you will need to include a FROM clause and join a sub-query which limits the number of rows. I would suggest using OFFSET AND FETCH instead of top so that you can skip X number of rows
You will also want to use the DATEADD function instead of directly subtracting a number from the DateTime function GETDATE(). I'm not certain but I think your query will subtract milliseconds. If you intend to go back a month I would suggest subtracting a month rather than 31 days. Alternatively it might be easier to specify an exact date like '2019-06-01'
For example:
TableA
- TableAID INT PK
- EmployeeID INT FK
- statusDate DATETIME
UPDATE TableA
SET statusDate = '2019-06-01'
FROM TableA
INNER JOIN
(
SELECT TableAID
FROM TableA
WHERE EmployeeID = ''
ORDER BY TableAID
OFFSET 0 ROWS
FETCH NEXT 5 ROWS ONLY
) T1 ON TableA.TableAID = T1.TableAID
Right now it looks like your original query is updating the table employee rather than a purchases table. You will want to replace my TableA with whichever table it is you're updating and replace TableAID with the PK field of it.
You can use a ROW_NUMBER to get a ranking by employee, then just update the first 15 rows.
;WITH EmployeeRowsWithRowNumbers AS
(
SELECT
T.*,
RowNumberByEmployee = ROW_NUMBER() OVER (
PARTITION BY
T.EmployeeID -- Generate a ranking by each different EmployeeID
ORDER BY
(SELECT NULL)) -- ... in no particular order (you should supply one if you have an ordering column)
FROM
emp.employee AS T
)
UPDATE E SET
statusDate = CASE
WHEN E.RowNumberByEmployee <= 5 THEN '2019-06-01'
WHEN E.RowNumberByEmployee BETWEEN 6 AND 10 THEN '2019-07-01'
ELSE '2019-08-01' END
FROM
EmployeeRowsWithRowNumbers AS E
WHERE
E.RowNumberByEmployee <= 15
I have the following query:
SELECT *
FROM dbo.mytable FOR system_time BETWEEN #rowEffFrom AND #rowEffTo t
WHERE t.anothertableid = 1
ORDER BY t.rowefffrom
My table has the following columns relevant to this question:
Id, AnotherTableId (FK), Description, RowEffFrom, RowEffTo
What I have done is get an entry from tblAnotherTable's history matching certain criteria. I then set #rowEffFrom and #rowEffTo as the RowEffFrom and RowEffTo for the retrieved row (top 1).
myTable has a many to one relationship with tblAnotherTable.
I want to retrieve the latest version of all entries between the #rowEffFrom and #rowEffTo, but one per Id.
e.g.
if my query above returns 2 rows, both with Id of 11, then I just want the most recent. If it returns 6 rows with ids 11,12,13 I want 3 rows with the latest of each version.
Nevermind, the answer is:
SELECT *
FROM ( SELECT Row_number() OVER (partition BY id ORDER BY rowefffrom DESC) rownumber,
*
FROM dbo.mytable FOR system_time BETWEEN #rowEffFrom AND #rowEffTo t
WHERE t.anothertableid = 1 ) mt
WHERE mt.rownumber = 1
We have two tables, Status and Main.
Status table:
statusId int pk
Status nvarchar(100)
Sample data
1 Open
2 Cancelled
3 Under Review
4 Awarded
5 Archived
6 Closed
7 Removed
8 Library CM Subcontractor
9 Property Sales
Main table:
statusid int fk to Status table
Type nvarchar(50)
Sample data
StatusID Type
1 Bid
1 Quote
1 RFP
We are trying to get a count of current Type from main table and a count of Status from Status table and display the results in the following format:
Current [count]
Current Bid [count]
Current RFP [count]
Sole Source [count]
Library CM Subcontracting [count]
Current Quotes [count]
Property Sales [count]
Closed [count]
Cancelled [count]
Under Review [count]
Awarded [count]
Archives [count]
The word count in square brackets represent the total number of records for a particular fieldname.
My code so far, produces the count of current Bids, current Quotes and current RFPs from the main table.
However, my count of Status are getting duplicated.
Below is the code I am using:
select
case when status.status ='Open' then Main.Type else status.status end as Name
, count(*) as total
from Main
inner join status on Main.Bidstatus = status.statusid
group by
case when status.status ='Open' then Main.Type else status.status end
, Main.Type
Any idea how to modify the code to produce unique counts of the records?
Your question is still not very clear, your requirements keep changing. However, if you need the total count of the main type records and a total count of the substatus records, you can use the following queries separated or UNIONed depending on what you need:
SELECT Main.Type Name ,
COUNT( * )AS Count
FROM Main
INNER JOIN status ON Main.Bidstatus = status.statusid
GROUP BY Main.Type
--optional:
--UNION
SELECT status.statusid Name ,
COUNT( * )AS Count
FROM Main
INNER JOIN status ON Main.Bidstatus = status.statusid
GROUP BY status.statusid
I am having an issue with my date values and the data types for the date field is date-time but at the sametime i am getting a lot of records for the same id within 48 hours. The goal is just to return one record only if patient makes visit to the hospital within 48. For example if patient A goes to ER on 1/1/2014 and again goes back to 1/2/2014 then i only want to show the first visit which 1/1/2014. I really believe the issue is at this line
AND A.[ADMT_TS] < DateAdd(d, 2, ADMT_TS)
and i think i need to do some conversion first in order to get the correct values.
here is my query and please not that i have other queries before the select statement here but i am only posting this section which where i am trying to get the first 48 hours.
SELECT [ID], [LOCATION], [ADMT_TS]
FROM ERS WHERE RN = 1
UNION ALL
SELECT [ID], [LOCATION], [ADMT_TS]
FROM ERS A
WHERE RN > 1 AND EXISTS (SELECT 1 FROM ERS WHERE RN = 1 AND [ID] = A.[ID])
AND NOT EXISTS(SELECT 1 FROM ERS WHERE RN = 1 AND [ID] = A.[ID] AND A.[ADMT_TS] < DateAdd(d, 2, ADMT_TS))
This will work but may not be the best option. If you post some data and give us an idea of how many rows may/will be in ERS table, I can adjust the query if needed
SELECT [Id]
,[Loc]
,MIN([admt_ts])
FROM [NewJunk].[dbo].[ERS]
WHERE RN = 1
GROUP BY id, loc
SELECT part_number,
price,
(Select max(sent_to_t) AS 'T' From [CIMSDB].[dbo].[price] where sent_to_t < '06/04/2013' Group by part_number)
FROM [CDB].[dbo].[part]PAB Inner Join [CDB].[dbo].[price] PR
ON PA.part_id = PR.part_id
Order By part_number
What I am trying to do is get a list of parts, and thier prices, for the most recent send_to_t date that is before 6/4. I am currently recieving -"Error Message
Server: Msg 164, Level 15, State 1, Line 1
Each GROUP BY expression must contain at least one
column that is not an outer reference."
You don't need a MAX at all (which is uncorrelated with the main query above, hence the error). Even if correlated, it would give you the most recent send_to_t value before some date but not the price on that date. It would simply give the most recent price with an unconnected date.
You asked (my bold)
get a list of parts, and their prices, for the most recent send_to_t date that is before 6/4
This gives you the most recent price for a part before 06/04/2013
Basically, a "top 1 per group" but with a date filter)
SELECT
part_number,
price,
sent_to_t
FROM
(
SELECT
part_number,
price,
sent_to_t,
ROW_NUMBER() OVER (PARTITION BY part_number ORDER BY sent_to_t DESC) AS rn
FROM
[CDB].[dbo].[part] PAB
Inner Join
[CDB].[dbo].[price] PR ON PAB.part_id = PR.part_id
WHERE
sent_to_t < '06/04/2013'
) X
WHERE
X.rn = 1
ORDER BY
part_number;
Note 06/04/2013 is ambiguous: is it 6th April or 4th June? You should use yyyymmdd for safety