Filtering down SQL To one value? [duplicate] - sql-server

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 1 year ago.
I'm writing a query for SAP B1,using Microsoft SQL Server Management Studio 17.
I am wanting to return the "MIN" DocDate, but show the field "ShipDate" alongside it, with only one result...
SELECT T0.ItemCode,
T3.ShipDate AS 'Next Date',
MIN(T3.DocDate) AS 'OrderDate'
FROM OITM T0
LEFT OUTER JOIN POR1 T3 ON T0.ItemCode = T3.ItemCode
WHERE T3.LineStatus = 'O' AND T3.ShipDate > GETDATE()
Group By T0.Itemcode, T3.ShipDate
This returns the following results;
ItemCode
ShipDate
OrderDate
VT3021026
2021-05-14
2021-05-04
VT3021026
2021-06-01
2021-05-10
This is an example of what one single item is returning, however I want to return only one value for each item. Almost like a "TOP 1" for each individual item. (obviously top 1 won't work in the overall select clause because it will be required to produce a list of multiple items)

If I understand you correctly, then this code will solve the problem.
DECLARE #date datetime2 = GETDATE();
WITH T(ItemCode, OrderDate) AS
(
SELECT
T0.ItemCode,
MIN(T3.DocDate) AS 'OrderDate'
FROM OITM T0
LEFT JOIN POR1 T3
ON T0.ItemCode = T3.ItemCode
WHERE T3.LineStatus = 'O'
AND T3.ShipDate > #date
GROUP BY T0.Itemcode, T3.ShipDate
)
SELECT T.ItemCode,
T4.ShipDate AS 'Next Date',
T.OrderDate
FROM T
LEFT JOIN POR1 T4
ON T.[OrderDate] = T4.DocDate
AND T.ItemCode = t4.ItemCode;

Related

SQL Server ISNULL not working in multi table selection

I'm very new to SQL server and I'm trying to get the maximum price of an item based on the update of table and if is null to replace the null able value with zero.
Here is what I did:
DECLARE #itemid BIGINT
SELECT
(SELECT ISNULL(MAX(ITEM_SUPPLIER_PRICE.Price), 0.00)
FROM ITEM_SUPPLIER_PRICE
WHERE (ITEM_SUPPLIER_PRICE.item_id = 7)) AS price,
itemunits.unit_id,
itemunits.unit_name
FROM
ITEM_SUPPLIER_PRICE
INNER JOIN
Items ON ITEM_SUPPLIER_PRICE.item_id = Items.Item_id
INNER JOIN
itemunits ON Items.Item_unit_id = itemunits.unit_id
WHERE
(Items.Item_id = 7)
GROUP BY
itemunits.unit_id, itemunits.unit_name,
ITEM_SUPPLIER_PRICE.update_date
ORDER BY
ITEM_SUPPLIER_PRICE.update_date DESC;
I think you're just looking for the max price in the group. Since prices probably can't be negative, the second option below should be equivalent but I throw it in just in case the problem is there.
SELECT
COALESCE(MAX(isp.Price), 0.00) AS price1,
MAX(COALESCE(isp.Price, 0.00)) AS price2,
iu.unit_id,
iu.unit_name
FROM ITEM_SUPPLIER_PRICE isp
INNER JOIN Items i ON i.item_id = isp.Item_id
INNER JOIN itemunits iu ON iu.unit_id = i.Item_unit_id
WHERE i.Item_id = 7
GROUP BY
iu.unit_id,
iu.unit_name,
isp.update_date
ORDER BY isp.update_date desc;

Get's records where gap between two dates is less than or equal to 5 days

I have two tables: tickets with unique ticket id and tickethistory with multiple records of a ticket (like open,attend,forward,close etc). Want to get records of
customers whose current ticket is open and last closed ticket is within 5 days gap. Using following query gives multiple records of closed tickets. Want last closed ticket actiondate in order to calculate days gap. If current open ticket and last closed ticket are within 5 days gap, want to consider current ticket as repeated.
SELECT A.ticketId,A.username,A.status,A.areaName,A.subject
,d.deptId,d.action,d.actionDate odate,g.actionDate cdate,g.status
FROM tb_tickets A
INNER JOIN (SELECT action, actiondate, ticketId, deptId FROM tb_ticketHistory WHERE action='Open') d
on a.ticketId = d.ticketid
INNER JOIN (SELECT th.ticketid, tt.username, tt.status, actiondate FROM tb_ticketHistory th
INNER JOIN tb_tickets tt
on th.ticketId = tt.ticketId WHERE th.action='closed') g
on a.username = g.username
WHERE d.deptId=5 AND a.status!='closed'
ORDER BY ticketId ASC
Since you haven't give exact structure and sample data, it's tough to give an exact answer. but you can try following code by tweaking it as your structure -
select CurrentOpenTickets.customerid, CurrentOpenTickets.ticketid from
(
select customerid, t.ticketid, actiondate from [dbo].[tb_ticketHistory ] th
inner join [dbo].[tb_Tickets] t on t.ticketid = th.ticketid
where t.status != 'C'
) CurrentOpenTickets
inner join
(select customerid, t.ticketid, actiondate from [dbo].[tb_ticketHistory ] th
inner join [dbo].[tb_Tickets] t on t.ticketid = th.ticketid
where th.status = 'C'
) PastClosedTickets
on CurrentOpenTickets.customerid = PastClosedTickets.customerid and datediff(DAY, CurrentOpenTickets.actiondate, PastClosedTickets.actiondate) <= 5

Complete Select Statement ELSE a defaulted value?

I'm wondering if there is a way to have a complete select statement and if no row is returned to return a row with a default value in a specific field (SQL Server)? Here's a generic version of my SQL to better explain:
SELECT COUNT(CASE WHEN CAST(c.InjuryDate as DATE)>DATEADD(dd,-60, getdate ()) THEN b.InjuryID end) InjuryCount, a.PersonID
FROM Person_Info a
JOIN Injury_Subject b on b.PersonID=a.PersonID
JOIN Injury_Info c on c.InjuryID=b.InjuryID
WHERE EXISTS (SELECT * FROM Hospital_Record d WHERE d.PersonID=b.PersonID and d.InjuryID=b.InjuryID) --There could be multiple people associated with the same InjuryID
GROUP BY a.PersonID
If NOT EXISTS (SELECT * FROM Hospital_Record d WHERE d.PersonID=a.PersonID) THEN '0' in InjuryCount
I want a row for each person who has had an injury to display. Then I'd like a count of how many injuries resulted in hospitalizations in the last 60 days. If they were not hospitalized, I'd like the row to still be generated, but display '0' in InjuryCount column. I've played with this a bunch, moving my date from the WHERE to the SELECT, trying IF ELSE combos, etc. Could someone help me figure out how to get what I want please?
It's hard to tell without an example of input and desired output, but I think this is what you are going for:
select
InjuryCount = count(case
when cast(ii.InjuryDate as date) > dateadd(day,-60,getdate())
then i.InjuryId
else null
end
)
, p.PersonId
from Person_Info p
left join Hosptal_Record h on p.PersonId = h.PersonId
left join Injury_Subject i on i.PersonId = h.PersonId
and h.InjuryId = i.InjuryId
left join Injury_Info ii on ii.InjuryId = i.InjuryId
group by p.PersonId;

Running 3-Tier T-SQL Query for Report

First question here so please excuse any mistakes...
I am trying to write a SQL Query for an SSRS report and I am totally confused when it comes to my joins.
Background: I have 3 tables that are relevant
Publishers - This is essentially a list of people
Publisher Reports - This is a list of records (related to the Publisher table) that details the work they have completed in a month period.
Report Months - This is a list of records (related to the Publisher Reports table) that relates to a specific month and year. On these records they have an indicator to show whether they relate to the previous six month period.
What i am trying to do is get a list of Publishers who have not submitted a publisher report that is related to a Report Month record within the last 6 months. My desired output is a list of Publishers in on column with the Report Month(s) that they are missing in the next column.
I am really struggling how to do it... I had thought of it as a three step process...
--STEP 1 - Get list of report months that are included in the last 6 months
WITH ACTIVE6MREPM AS
(
SELECT r.jajw_name,
r.jajw_CalendarDate
FROM jajw_reportmonthBase r
WHERE r.jajw_IncludedIn6MonthReport = '1'
),
--STEP 2 - Get list of all publishers
ACTIVEPUBS AS
(
SELECT c.FullName,
c.ContactId
FROM ContactBase c
WHERE c.statecode = '0'
AND c.jajw_CongregationAssignment != 640840001
AND c.jajw_CongregationAssignment != 640840006
AND c.jajw_CongregationAssignment != 640840005
--AND q.jajw_FieldServiceGroups = (#Field_Service_Group)
),
--STEP 3 - Get List of Publisher Reports for the selected Report Months
RELEVANTREPORTS AS
(
SELECT r.jajw_reportId AS Publisher_Report_GUID,
r.jajw_PublisherId AS Publisher_GUID,
r.jajw_ReportMonthId AS ReportMonth_GUID,
m.jajw_name AS ReportMonth_Name
FROM jajw_reportBase r
INNER JOIN jajw_reportmonthBase m ON r.jajw_ReportMonthId = m.jajw_reportmonthId
WHERE r.jajw_ReportPeriod6Month = '1'
ORDER BY m.jajw_CalendarDate
After these three, I want to create my list as described above and this is the bit that has me stumped! Any help would be greatly appreciated!
Thanks!
I think you can shorten your code a lot... here's a shot at it without having test data... be sure to read the comments and add in the join condition and check the where clause.
with cte as(
SELECT r.jajw_reportId AS Publisher_Report_GUID,
r.jajw_PublisherId AS Publisher_GUID,
r.jajw_ReportMonthId AS ReportMonth_GUID,
m.jajw_name AS ReportMonth_Name,
c.FullName,
c.ContactId
FROM jajw_reportBase r
INNER JOIN jajw_reportmonthBase m ON
r.jajw_ReportMonthId = m.jajw_reportmonthId
INNER JOIN ContactBase c on --what ever condition is appropiate
WHERE r.jajw_ReportPeriod6Month = '1'
and m.jajw_IncludedIn6MonthReport = '1' --maybe put this here, or does the above do the same thing?
ORDER BY m.jajw_CalendarDate)
select
p2.FullName,
p2.ReportMonth_Name
from cte p
right join(select distinct
ReportMonth_Name, FullName
from ContactBase
left join jajw_reportmonthBase on 1=1) p2 on p2.FullName = p.FullName and p2.ReportMonth_Name = p.ReportMonth_Name
where
ContactId in (select ContactId from cte group by ContactId having count(distinct ReportMonth_GUID) < 6)
and p.FullName is null
Here is an example using test data.
declare #pub table (pubname varchar(56), ReportMonthName varchar(16))
insert into #pub (pubname,ReportMonthName) values
('a','Jan'),
('a','Feb'),
('a','Mar'),
('a','Apr'),
--publisher a is missing May and Jun
('b','Jan'),
('b','Feb'),
('b','Mar'),
('b','Jun')
--publisher b is missing Apr and May
declare #dt table (ReportMonthName varchar(16))
insert into #dt (ReportMonthName) values
('Jan'),
('Feb'),
('Mar'),
('Apr'),
('May'),
('Jun')
select
p2.pubname
,p2.ReportMonthName
from #pub p
right join(
select distinct
p.pubname
,d.ReportMonthName
from #pub p
left join #dt d on 1=1)p2 on p2.pubname = p.pubname and p2.ReportMonthName = p.ReportMonthName where p.pubname is null

How to merge a select statement with a calculated value as new columns? [duplicate]

This question already has answers here:
How to merge a select statement with a new dynamic values as columns?
(4 answers)
Closed 9 years ago.
In my sql server code, I have this select statement
select distinct
a.HireLastName,
a.HireFirstName,
a.HireID,
a.Position_ID,
a.BarNumber,
a.Archived,
a.DateArchived,
b.Position_Name
from NewHire a
join Position b on a.Position_ID = b.Position_ID
join WorkPeriod c on a.hireID = c.HireID
where a.Archived = 0 and c.InquiryID is not null
order by a.HireID DESC, a.HireLastName, a.HireFirstName
And I want to add a new column to it. However this column is not a column from a table, its just used to store a float from a calculation I make from existing columns.
The number I get is calculated like this:
#acc is the a.HireID from the above select statement.
CAST((select COUNT(*) from Hire_Response WHERE HireID = #acc AND (HireResponse = 0 OR HireResponse = 1)) as FLOAT) /
CAST((select COUNT(*) from Hire_Response WHERE HireID = #acc) as FLOAT)
How can I do this?
Thanks.
You can use the code that GBN did for you on your other question as a sub-query
select distinct
a.HireLastName,
a.HireFirstName,
a.HireID,
a.Position_ID,
a.BarNumber,
a.Archived,
a.DateArchived,
b.Position_Name,
d.percentage
from NewHire a
inner join Position b on a.Position_ID = b.Position_ID
inner join WorkPeriod c on a.hireID = c.HireID
left join (select NH.HireID, ISNULL(1E0 * COUNT(CASE WHEN HireResponse IN (0,1) THEN HR.HireID END) / NULLIF(COUNT(HR.HireID), 0) , 0) AS percentage
from NewHire NH LEFT JOIN Hire_Response HR ON NH.HireID = HR.HireID
group by NH.HireID) d
ON a.HireID = d.HireID
where a.Archived = 0 and c.InquiryID is not null
order by a.HireID DESC, a.HireLastName, a.HireFirstName
... this will add the column percentage to your current query. This could probably be improved, but it should give you a god idea of how you can bring the results of your questions together.

Resources