Handle condition in select statement - sql-server

I have a table like this:
customer:
customerID joineddate
111 2004-12-10 00:00:00.000
111 2004-12-10 00:00:00.000
111 2004-12-10 00:00:00.000
211 2004-12-10 00:00:00.000
231 2004-12-10 00:00:00.000
231 2004-11-10 00:00:00.000
411 2008-12-10 00:00:00.000
531 2009-12-10 00:00:00.000
I have written the query from 2 tables where I do a join and get the result like the above. But I need to get the result like this where I need to input my condition and get the result like below.
customerID joineddate indicator
111 2004-12-10 00:00:00.000 3
211 2004-12-10 00:00:00.000 1
231 2004-12-10 00:00:00.000 1
231 2004-11-10 00:00:00.000 1
411 2008-12-10 00:00:00.000 1
531 2009-12-10 00:00:00.000 1

Having absolutely no clue what your other table is named or how it is related to the customer table, here is my best guess:
SELECT c.customerID, o.joineddate, indicator = COUNT(*)
FROM dbo.customer AS c
INNER JOIN dbo.[other table] AS o
ON c.CustomerID = o.CustomerID
GROUP BY c.customerID, o.joineddate;

Google for keyword
GROUP BY
and the
COUNT()
function.

Related

SQL Server : subquery to return the latest cost revision of a unit of inventory on hand

I have 2 tables that I am trying to marry together to end up with a result, which tells me the standard cost of the item that is still on hand (based on a FIFO costing method). The first table is inventory receipts , which tells me the parts left to consume and the transaction dates of those receipts. The second is a standard cost view which tells me the cost history of the item (rev = revision number which increases by 1 each time the standard cost of the part gets updated).
I currently have a solution which works using TOP 1 and ordering by DESC on effective date of cost, however, when I run this for the entire inventory list of the company , it takes over 16 minutes due to the TOP 1 sub-query inefficiency and cost.
Sample data (inventory receipts on hand):
partID warehouse transDate seqn orderID qtytoconsume
-------------------------------------------------------------
P0003 W01 2019-01-24 00:00:00.000 1 ORD0187 2
P0003 W01 2018-06-24 00:00:00.000 1 ORD0099 3
P0003 W01 2018-11-24 00:00:00.000 1 ORD0165 1
P0003 W04 2018-12-14 00:00:00.000 1 ORD0175 1
P0002 W02 2019-01-14 00:00:00.000 1 ORD0184 4
P0002 W02 2019-03-24 00:00:00.000 1 ORD0199 1
P0002 W03 2018-05-27 00:00:00.000 1 ORD0093 1
P0002 W03 2018-12-06 00:00:00.000 1 ORD0171 2
P0001 W04 2018-09-09 00:00:00.000 1 ORD0146 5
P0001 W02 2019-04-22 00:00:00.000 1 ORD0200 4
P0001 W03 2019-03-29 00:00:00.000 1 ORD0200 2
P0001 W02 2018-02-14 00:00:00.000 1 ORD0061 1
and standard cost view:
partID document effdate rev costamt
-----------------------------------------------------
P0001 IV0001 2018-01-28 00:00:00.000 1 1000.00
P0001 IV0023 2018-06-30 00:00:00.000 2 1200.00
P0001 IV0045 2019-01-01 00:00:00.000 3 1300.00
P0002 IV0001 2018-01-28 00:00:00.000 1 45.00
P0002 IV0013 2018-04-10 00:00:00.000 2 42.00
P0002 IV0045 2019-01-01 00:00:00.000 3 56.00
P0003 IV0001 2018-01-28 00:00:00.000 1 23400.00
P0003 IV0003 2018-02-20 00:00:00.000 2 11200.00
P0003 IV0045 2019-01-01 00:00:00.000 3 15000.00
P0003 IV0047 2019-02-27 00:00:00.000 4 13400.00
P0003 IV0078 2019-05-03 00:00:00.000 5 14670.00
And my result (which equals my expected result), but for large row sets is less than ideal.
partID warehouse transDate seqn orderID qty costamt
-------------------------------------------------------------
P0003 W01 2019-01-24 00:00:00.000 1 ORD0187 2 15000.00
P0003 W01 2018-06-24 00:00:00.000 1 ORD0099 3 11200.00
P0003 W01 2018-11-24 00:00:00.000 1 ORD0165 1 11200.00
P0003 W04 2018-12-14 00:00:00.000 1 ORD0175 1 11200.00
P0002 W02 2019-01-14 00:00:00.000 1 ORD0184 4 56.00
P0002 W02 2019-03-24 00:00:00.000 1 ORD0199 1 56.00
P0002 W03 2018-05-27 00:00:00.000 1 ORD0093 1 42.00
P0002 W03 2018-12-06 00:00:00.000 1 ORD0171 2 42.00
P0001 W04 2018-09-09 00:00:00.000 1 ORD0146 5 1200.00
P0001 W02 2019-04-22 00:00:00.000 1 ORD0200 4 1300.00
P0001 W03 2019-03-29 00:00:00.000 1 ORD0200 2 1300.00
P0001 W02 2018-02-14 00:00:00.000 1 ORD0061 1 1000.00
My query is:
SELECT
ioh.*, sc.costamt, sc.effdate
FROM
inventoryonHand ioh
LEFT JOIN
standardcosts sc ON sc.partID = ioh.partID
AND sc.effdate = (SELECT TOP 1 sc2.effDate
FROM standardcosts sc2
WHERE sc2.partID = sc.partID
AND sc2.effDate < ioh.transDate
ORDER BY sc2.partID ASC, sc2.effDate DESC);
Thanks so much guys!
You can try it (if your consider partID and transdate can be unique into your inventoryonHand table, otherwhise use partition by on his key) :
select * from (
select f1.*,
f2.effdate, f2.costamt, f2.rev,
row_number() over(partition by f1.partid, f1.transdate order by f2.effdate desc, f2.rev desc) as lasteffDaterank
from inventoryonHand f1
left outer join standardcosts f2 on f1.partid=f2.partid and f2.effDate < f1.transDate
) tmp
where lasteffDaterank=1
You could try to simplify the subquery using max().
(SELECT max(sc1.effdate)
FROM standardcosts sc2
WHERE sc2.partid = sc.partid
AND sc2.effdate < ioh.transdate)
For performance try an index on standardcosts (partid ASC, effdate DESC).
You can ty this too, not really sur its better ;)
select f1.*, f3.*
from inventoryonHand f1
outer apply
(
select top 1 f2.costamt from standardcosts f2
where f1.partid=f2.partid and f2.effDate < f1.transDate
order by f2.effdate desc, f2.rev desc
) f3

MSSQL - split records per week_start and week_end

I have a table similar to the one represented below.
myID | some data | start_date | end_date
1 Tom 2016-01-01 2016-05-09
2 Mike 2015-03-01 2017-03-09
...
I have a function that when provided with start_date, end_date, interval (for example weeks)
returns me data as below. (splits the start and end dates to week intervals)
select * from my_function('2016-01-01','2016-01-12', 'ww')
2015-12-28 00:00:00.000 | 2016-01-03 00:00:00.000 15W53
2016-01-04 00:00:00.000 | 2016-01-10 00:00:00.000 16W1
2016-01-11 00:00:00.000 | 2016-01-17 00:00:00.000 16W2
I would like to be able to write a query that returns all of the values from the 1 table, but splits Start date and end date in to multiple rows using the function.
myID | some data | Week_start_date | Week_end_date | (optional)week_num
1 Tom 2015-12-28 2016-01-03 15W53
1 Tom 2016-01-04 2016-01-10 16W1
1 Tom 2016-01-11 2016-01-17 16W2
...
2 Mike etc....
Could someone please help me with creating such a query ?
select myID,some_data,b.Week_start_date,b.Week_end_date,b.(optional)week_num from #a cross apply
(select * from my_function('2016-01-01','2016-01-12', 'ww'))b
like sample data i tried
create table #a
(
myID int, some_data varchar(50) , start_date date, end_date date)
insert into #a values
(1,'Tom','2016-01-01','2016-05-09'),
(2,'Mike','2015-03-01','2017-03-09')
here iam keeping function result into one temp table
create table #b
(
a datetime,b datetime, c varchar(50)
)
insert into #b values
('2015-12-28 00:00:00.000','2016-01-03 00:00:00.000','15W53'),
('2016-01-04 00:00:00.000','2016-01-10 00:00:00.000','16W1 '),
('2016-01-11 00:00:00.000','2016-01-17 00:00:00.000','16W2 ')
select myID,some_data,b.a,b.b,b.c from #a cross apply
(select * from #b)b
output like this
myID some_data a b c
1 Tom 2015-12-28 00:00:00.000 2016-01-03 00:00:00.000 15W53
1 Tom 2016-01-04 00:00:00.000 2016-01-10 00:00:00.000 16W1
1 Tom 2016-01-11 00:00:00.000 2016-01-17 00:00:00.000 16W2
2 Mike 2015-12-28 00:00:00.000 2016-01-03 00:00:00.000 15W53
2 Mike 2016-01-04 00:00:00.000 2016-01-10 00:00:00.000 16W1
2 Mike 2016-01-11 00:00:00.000 2016-01-17 00:00:00.000 16W2
Based on your current result and expected result,the only difference ,i see is myID
so you will need to frame your query like this..
;with cte
as
(
select * from my_function('2016-01-01','2016-01-12', 'ww')
)
select dense_rank() over (order by somedata) as col,
* from cte
Dense Rank assigns same values for the same partition and assigs the sequential value to next partition ,unlike Rank
Look here for more info:
https://stackoverflow.com/a/7747342/2975396

Left outer join with where clause from main table

select
b.d,
sum(pic_sam)/60
from
inter b
left join
sah
on d=date
where
b.d between '01 May 2016' and '06 May 2016'
group by
b.d
order by
b.d
I have written a sql script like above which is showing data like below
2016-05-01 00:00:00.000 NULL
2016-05-02 00:00:00.000 2608.422500
2016-05-03 00:00:00.000 20236.230333
2016-05-04 00:00:00.000 21398.398166
2016-05-05 00:00:00.000 0.000000
2016-05-06 00:00:00.000 0.000000
Now I need to put another condition here which is
select
b.d,
sum(pic_sam)/60
from
inter b
left join
sah a
on d=date
where
b.d between '01 May 2016' and '06 May 2016' **and a.line_code like 'K%;**
group by
b.d
order by
b.d
then data should be display like below but the second script is not working as per below requirement.
2016-05-01 00:00:00.000 NULL
2016-05-02 00:00:00.000 500.422500
2016-05-03 00:00:00.000 10000.230333
2016-05-04 00:00:00.000 5000.398166
2016-05-05 00:00:00.000 0.000000
2016-05-06 00:00:00.000 0.000000
Move the right table filter to ON condition
SELECT b.d,
Sum(pic_sam) / 60
FROM inter b
LEFT JOIN sah a
ON d = date
AND a.line_code LIKE 'K%'
WHERE b.d BETWEEN '01 May 2016' AND '06 May 2016'
GROUP BY b.d
ORDER BY b.d

Most recent entry of a record in an Access report

I am trying to retrieve the most recent entry of a record in an Access report. The query I have gives me the results in SQL-Server but row_number is not compatible with Access. Its been suggested that I use the max function in Access. Can you assist me in generating this report?
SELECT cID, CName, Address, Project#, JobOwner, SubStatusID, Status, JNJobID, JNNote
FROM (
SELECT
cID, CName, Address, Project#, JobOwner, SubStatusID, Status, JNJobID, JNNote
, ROW_NUMBER() OVER (PARTITION BY JNJobID ORDER BY JNDate DESC) AS r
FROM [JobNotes]
Left JOIN Jobs ON [JobNotes].JNJobID = Jobs.JobID
Left JOIN Addresses ON Jobs.JobAddressID = Addresses.AddressID
Left JOIN Customers ON Jobs.JobCustomerID = Customers.CID
Left JOIN Status ON Jobs.JobSubStatusID = Status.StatusID
) x
WHERE r = 1 and customerID = 134 and jobsubstatusid <> 14 and jobsubstatusid <> 15 and jobsubstatusid <> 16 and jobsubstatusid <> 42 and jobsubstatusid <>38 and jobsubstatusid <>75
Jobs Table
JobID Project# JobOwner JobStatusID AddressID JobCustomerID
6972 PN1 John 1 333 222
6973 PN2 Sarah 3 444 666
6974 PN3 James 6 555 777
Address Table
AddressID Address
333 1333 Janes Ln
444 5555 Davis Blvd
555 888 Post Rd
Customer Table
CID CName
222 Builder
666 HomeOwner
777 HOA
JobNotes Table
JobNotesID JNJobID JNDate JNNote
11800 6972 2016-03-15 00:00:00.000 Example 1
11874 6972 2016-03-17 00:00:00.000 Example 2
12181 6972 2016-03-25 00:00:00.000 Example 3
12006 6973 2016-03-21 00:00:00.000 Example 4
11961 6974 2016-03-18 00:00:00.000 Example 5
11924 6974 2016-03-17 00:00:00.000 Example 6
JobNotes Table
CID CName Address Project# JobOwner SubStatusID Status JNJobID JNNote
222 Builder 1333 Janes Ln PN1 John 1 Sales 6972 Example 3
666 HomeOwner 5555 Davis Blvd PN2 Sarah 3 Design 6973 Example 4
777 HOA 888 Post Rd PN3 James 6 Construction 6974 Example 6

How to delete the duplicate based on date

I have a table where I have several cust_id duplicates. I would like to keep the row where prendate_next is nearest to the current date and delete the rest of the duplicates. Please help me how. I am new to this
cust_id prendate_next
1000105737 2014-11-30 00:00:00.000
1000105836 2014-11-20 00:00:00.000
1000143646 2014-11-10 00:00:00.000
1000143646 2015-03-09 00:00:00.000
1000179487 2014-12-05 00:00:00.000
1000182253 2015-01-01 00:00:00.000
1000192740 2014-10-02 00:00:00.000
1000192740 2015-01-10 00:00:00.000
1000199419 2015-09-30 00:00:00.000
1000170578 2014-12-26 00:00:00.000
1000188890 2015-06-23 00:00:00.000
1000189075 2015-03-01 00:00:00.000
1000189075 2015-03-01 00:00:00.000
1000189144 2015-04-04 00:00:00.000
;WITH cte AS (
SELECT cust_id, prendate_next,
ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY ABS(DATEDIFF(DAY,prendate_next,GETDATE()))) AS RowNumber
FROM MyTable
)
DELETE MyTable
FROM MyTable
INNER JOIN cte ON MyTable.cust_id = cte.cust_id
AND MyTable.prendate_next = cte.prendate_next
WHERE cte.RowNumber != 1
ABS(DATEDIFF(DAY,prendate_next,GETDATE())) counts how many days prendate_next is from today.

Resources