group by clause - sql
i have a table called table1 and it has following columns.
suppose there are records like localamount is 20,000, 30000,50000, 100000 then as per my condition i have to delete records from this table according to the group by set of site id, till id, transid,shift id where localamount exceeds 10,000... the rest of the records can be available?
my aim is to delete rows from this table where local amount is exceeds 10,0000 according to site id, till id, transid,shift id
SiteId varchar(10),
TillId tinyint,
ShiftId int,
TransId int,
TranDate datetime,
SettlementType varchar(5),
CreditCardNumber varchar(25),
ProductTypeCode varchar(10),
NewProductTypeCode varchar(10),
TransactionType int,
ForeignAmount money,
LocalAmount money,
ProductCode varchar(10)
Im not sure I understand what you are saying, but couldn't you do this without a group by?
delete from table1 where LocalAmount > 10,0000[sic] and SiteId = whatever and TillId = whatever...
obviously take the [sic] out...
Assuming you want to delete the whole group where the sum is > 10000
;with cte as
(
select sum(localamount) over
(partition by siteid, tillid, transid,shiftid) as l,
* from table1
)
delete from cte where l>10000
Related
Get SQL Distinct Row Without NULL Values
I'm trying to get a distinct row using SQL from set of records that have matching key/id value, but NULLs in different columns. Hard to explain so please see screenshot. Any ideas? create temporary table my_table ( id varchar(30), segmentdate1 date, converted1 varchar(10), segmentdate2 date, converted2 varchar(10) ); insert into my_table ( id, segmentdate1, converted1, segmentdate2, converted2 ) values ('Michael','9/15/2020','No',NULL,NULL), ('Michael',NULL,NULL,'7/1/2019','Yes') ;
You seem to want aggregation: select id, max(segmentdate1) as segmentdate1, max(converted1) as converted1, max(segmentdate2) as segmentdate2, max(converted2) as converted2 from t group by id; Note: I made up names for the columns so they are unique. This is probably a result set created from another query. That query probably has the wrong group by keys. You should probably fix that query.
declare #my_table table ( id varchar(30), segmentdate1 date, converted1 varchar(10), segmentdate2 date, converted2 varchar(10) ); insert into #my_table ( id, segmentdate1, converted1, segmentdate2, converted2 ) values ('Michael','9/15/2020','No',NULL,NULL), ('Michael',NULL,NULL,'7/1/2019','Yes') ; select id,max(isnull(segmentdate1,'1200-01-01')) segmentdate2 ,max(isnull(converted1,'')) converted1, max(isnull(segmentdate2,'1200-01-01')) segmentdate2 ,max(isnull(converted2,'')) converted2 from #my_table group by id
Preparing Rules Based List for Promotions
I am trying to put together a promotions list based on a set of rules In table #productdetail I need to pick up items that have available =1 or available =2 and expected <=08052019 and not_sellable =0 From #product table I need to join id with pid in #productdetail and coalesce (vendor_id to get the vendor_id Using the vendor_id that I have got from the step above i need to get the vendorname from #vendor table.. From the #Asin table I need to select the latest lastconfirmedasin from the list of items selected in step 1 and also ensure that I should not pick up data from rows where disable =1 From the #pageviews table I need to get the number of pageviews perday for every item based on the lastconfirmedasin for the list of items selected in step 1 Here for every item if I have datetype =day and also datetype =month then I need to select data from datetype =day and select sum(pageviews)/count of days to get the sum of pageviews per day Also if I have only datetype =month then I need to select (sum(pageviews)(count of rows that have month)/30 Then in the promo table I need to select the average promo% got for the items selected in step 1..The average promo% is calculated as avg((pre_promo_price-promo_price)/promo_price*100))...This will be calculated at the vendor level...So if the vendor has 3 items then the average promo% is calculated as avg([avg((pre_promo_price-promo_price)/promo_price*100) Then the cost is taken based on if in the table #promo has the date in between or included in promo_start and promo_end (for example today's date being 08/16/2019 is included then the pre promo cost is to taken as the cost for that item otherwise the cost from #product_detail table should be taken Then I am calculating the priority of the items by vendor(meaning within each vendor ) prioritizing the items based on the power(calculated as pageviewsperday*price)-Higher value of an item within a vendor gets the first priority The tables: create table #productdetail ( itemid int, available int, expected date, isnotsellable int, pid int, vendor_id varchar(50), cost float, price float) insert into #productdetail values ('123','1',NULL,'1','1','201','180','200'), ('125','2','08/05/2019','0','1','NULL','40','60'), ('127','1',NULL,'0','1','201','60','80'), ('129','2',NULL,'0','2','203','80','100'), ('131','1',NULL,'0','2','203','70','90'), ('133','1',NULL,'1','2','203','90','110'), ('135','1',NULL,'0','7','206','110','130'), ('137','1',NULL,'0','8','207','120','140'), ('139','1',NULL,'0','8','207','30','50'), ('141','1',NULL,'0','8','207','40','60'), ('143','1',NULL,'0','11','210','60','80'), ('145','1',NULL,'0','11','210','70','90'), ('147','1',NULL,'1','11','210','50','70'), ('149','1',NULL,'0','11','210','20','40'), ('151','1',NULL,'0','15','211','30','50'), ('153','1',NULL,'0','16','NULL','40','60'), ('155','2','08/29/2019','1','15','211','60','80'), ('157','2','08/04/2019','1','18','216','30','50'), ('159','2','08/06/2019','0','19','217','20','40'), ('161','2','08/03/2019','0','20','218','60','80'), ('163','2','08/15/2019','0','21','NULL','90','110') create table #product (id int, vendor_id varchar(50) ) insert into #product values ('1','201'), ('1','201'), ('1','201'), ('2','203'), ('2','203'), ('2','203'), ('7','NULL'), ('8','207'), ('8','207'), ('8','207'), ('11','210'), ('11','210'), ('11','210'), ('11','210'), ('15','211'), ('15','211'), ('15','211'), ('16','206'), ('18','216'), ('19','NULL'), ('20','218'), ('21','219') create table #vendor (vendor_id varchar(50), vendorname varchar(50) ) insert into #vendor values ('201','cola'), ('203','foam'), ('207','fill'), ('210','falon'), ('211','chiran'), ('216','Hummer'), ('218','sulps'), ('219','culp'), ('217','jko'), ('206','JINCO') create table #asin (disable int, item_id int, lastconfirmed datetime2, lastconfirmedasin varchar(50) ) insert into #asin values ('0','123','12/19/18 10:19 PM','iopyu'), ('1','123','12/19/16 10:19 PM','hjyug'), ('1','125','5/19/19 10:19 PM','uirty'), ('0','125','12/19/16 10:19 PM','1yuio'), ('0','127','2/19/19 10:19 PM','klbnm'), ('1','127','12/19/18 10:19 PM','lopgh'), ('0','127','12/19/16 10:19 PM','nmbh'), ('0','129','11/19/16 10:19 PM','jklh'), ('0','131','11/19/19 10:19 PM','werat'), ('1','133','6/19/19 10:19 PM','vbnwe'), ('0','133','1/19/19 10:19 PM','mnwer'), ('0','133','11/19/17 10:19 PM','sdert'), ('0','135','6/19/19 10:19 PM','vbsdx'), ('0','137','6/19/17 10:19 PM','bnxct') create table #pageviews (startdate date, lastconfirmedasin varchar(50), noofpageviews int, datetype varchar(20)) insert into #pageviews values ('05/08/2017','hjyug','102','day'), ('09/05/2017','hjyug','201','day'), ('10/05/2019','hjyug','1002','day'), ('09/05/2018','iopyu','345','month'), ('10/06/2018','iopyu','545','month'), ('06/05/2019','1yuio','300','day'), ('06/06/2019','1yuio','200','day'), ('09/04/2019','uirty','150','day'), ('11/4/2019','uirty','200','day'), ('12/4/2019','nmbh','300','day'), ('04/15/2019','lopgh','400','day'), ('04/15/2019','klbnm','500','day'), ('04/16/2019','klbnm','1000','day'), ('04/15/2019','jklh','600','day'), ('04/15/2019','werat','700','day'), ('04/15/2019','sdert','800','day'), ('04/15/2019','mnwer','900','day'), ('04/15/2019','vbnwe','1000','day'), ('04/15/2019','vbsdx','1100','day'), ('04/25/2019','vbsdx','3000','day'), ('04/15/2019','bnxct','1200','month'), ('05/31/2019','bnxct','2200','month'), ('04/16/2019','bnxct','90','day'), ('04/17/2019','bnxct','100','day'), ('04/18/2019','bnxct','120','day') create table #promo (itemid int, promo_cost float, pre_promo_cost float, promo_start varchar(50), promo_end varchar(50)) insert into #promo values ('123','214.7','220','10/08/2019','22/08/2019'), ('123','225','230','01/02/2018','15/02/2018'), ('125','400','430','12/08/2019','19/08/2019'), ('125','380','390','15/02/2019','30/02/2019'), ('127','120','140','15/03/2019','30/03/2019'), ('129','80','100','15/04/2019','30/04/2019'), ('129','110','120','01/04/2019','10/04/2019'), ('131','80','100','01/02/2019','15/02/2019'), ('131','110','120','10/01/2019','15/01/2019'), ('133','230','420','10/01/2019','15/01/2019'), ('135','250','440','10/01/2019','15/01/2019'), ('137','270','460','10/01/2019','15/01/2019'), ('139','290','480','10/01/2019','15/01/2019'), ('141','310','500','10/01/2019','15/01/2019'), ('143','330','520','10/01/2019','15/01/2019'), ('145','350','540','10/08/2019','22/08/2019') create table #output (itemid int, available int, expected date, isnotsellable int, pid int, vendor_id varchar(50), vendorname varchar(50), lastconfirmedasin varchar(50), pageviewsperday int, promoavg float, cost float, price float, [power] int, [priority] int) insert into #output values ('151','1',NULL,'0','15','211','chiran','','0','0','30','50','0','1'), ('127','1',NULL,'0','1','201','cola','klbnm','750','6.3','60','80','60000','1'), ('125','2','08/05/2019','0','1','201','cola','','0','0','430','60','0','2'), ('143','1',NULL,'0','11','210','falon','','0','0','60','80','0','1'), ('145','1',NULL,'0','11','210','falon','','0','0','540','90','0','2'), ('149','1',NULL,'0','11','210','falon','','0','0','20','40','0','3'), ('137','1',NULL,'0','8','207','fill','bnxct','103','65.73','120','140','14420','1'), ('139','1',NULL,'0','8','207','fill','','0','0','30','50','0','2'), ('141','1',NULL,'0','8','207','fill','','0','0','40','60','0','3'), ('131','1',NULL,'0','2','203','foam','werat','700','30.16','70','90','63000','1'), ('135','1',NULL,'0','7','206','JINCO','vbsdx','2050','76','110','130','266500','1'), ('153','1',NULL,'0','16','206','JINCO','','0','0','40','60','0','2'), ('161','2','08/03/2019','0','20','218','sulps','','0','0','60','80','0','1') Code tried: ; WITH firstsel AS ( SELECT itemid, available, expected, isnotsellable, pid, vendor_id FROM #productdetail WHERE available = 1 AND isnotsellable = 0 UNION ALL SELECT itemid, available, expected, isnotsellable, pid, vendor_id FROM #productdetail WHERE available = 2 AND isnotsellable = 0 AND expected <= '20190805' ), addvendorid AS ( SELECT fs.itemid, fs.available, fs.expected, fs.pid, fs.isnotsellable, coalesce(fs.vendor_id, p.vendor_id) AS vendor_id FROM firstsel fs JOIN #product p ON fs.pid = p.id ), asinnumbered AS ( SELECT item_id, lastconfirmedasin, row_number() OVER (PARTITION BY item_id ORDER BY lastconfirmedasin DESC) AS rowno FROM #asin ) SELECT av.itemid, av.available, av.expected, av.isnotsellable, av.pid, av.vendor_id, v.vendorname, an.lastconfirmedasin, isnull(pv.pageviews, 0) AS pageviews, isnull(p.promoavg, 0) AS promoavg FROM addvendorid av JOIN #vendor v ON av.vendor_id = v.vendor_id LEFT JOIN (asinnumbered an JOIN (SELECT lastconfirmedasin, SUM(pageviews) AS pageviews FROM #pageviews GROUP BY lastconfirmedasin) AS pv ON an.lastconfirmedasin = pv.lastconfirmedasin) ON an.item_id = av.itemid AND an.rowno = 1 LEFT JOIN (SELECT itemid, avg((pre_promo_price-promo_price)/promo_price*100) AS promoavg FROM #promo GROUP BY itemid) AS p ON p.itemid = av.itemid ORDER BY av.itemid
Delete duplicate rows with soundex?
I have two tables, one has foreign keys to the other. I want to delete duplicates from Table 1 at the same time updating the keys on Table 2. I.e count the duplicates on Table 1 keep 1 key from the duplicates and query the rest of the duplicate records on Table 2 replacing them with the key I'm keeping from Table 1. Soundex would be the best option because not all the names are spelled right in Table 1. I have the basic algorithm but not sure how to do it. Help? So far this is what I have: declare #Duplicate int declare #OriginalKey int create table #tempTable1 ( CourseID int, <--- The Key I want to keep or delete SchoolID int, CourseName nvarchar(100), Category nvarchar(100), IsReqThisYear bit, yearrequired int ); create table #tempTable2 ( CertID int, UserID int, CourseID int, <---- Must stay updated with Table 1 SchoolID int, StartDateOfCourse datetime, EndDateOfCourse datetime, Type nvarchar(100), HrsOfClass float, Category nvarchar(100), Cost money, PassFail varchar(20), Comments nvarchar(1024), ExpiryDate datetime, Instructor nvarchar(200), Level nchar(10) ) --Deletes records from Table 1 not used in Table 2-- delete from Table1 where CourseID not in (select CourseID from Table2 where CourseID is not null) insert into #tempTable1(CourseID, SchoolID, CourseName, Category, IsReqThisYear, yearrequired) select CourseID, SchoolID, CourseName, Category, IsReqThisYear, yearrequired from Table1 insert into #tempTable2(CertID, UserID, CourseID, SchoolID, StartDateOfCourse, EndDateOfCourse, Type, HrsOfClass,Category, Cost, PassFail, Comments, ExpiryDate, Instructor, Level) select CertID, UserID, CourseID, SchoolID, StartDateOfCourse, EndDateOfCourse, Type, HrsOfClass,Category, Cost, PassFail, Comments, ExpiryDate, Instructor, Level from Table2 select cour.CourseName, Count(cour.CourseName) cnt from Table1 as cour join #tempTable1 as temp on cour.CourseID = temp.CourseID where SOUNDEX(temp.CourseName) = SOUNDEX(cour.CourseName) <--- The last part does not exactly work, gives me an error Error: Column 'Table1.CourseName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. UPDATE: Some of the names in CourseName have numbers in them too. Like some are in romans and numeral format. Need to find those too but Soundex ignores numbers.
SQL query Optimization help
I have the the following SQL query Declare #tempcalctbl Table ( ItemId varchar(50), ItemLocation varchar(50), ItemNo varchar(50), Width real, Unit varchar(50), date datetime ) Insert Into #tempcalctbl Select distinct SubId,ItemLocation,ItemNo, (ABS((Select width From #temptbl a Where ItemProcess ='P1'and a.ItemId = c.ItemId and a.ItemNo = c.ItemNo and a.ItemLocation = c.ItemLocation) -(Select width From #temptbl b Where ItemProcess ='P2' and b.ItemId = c.ItemId and b.ItemNo = c.ItemNo and b.ItemLocation = c.ItemLocation))) * 1000, Unit,date From #temptbl c Group by ItemId,ItemLocation,ItemNo,Unit,date I was wondering how to optimize this query. The idea is to find out the different in width (p1's item - p2's item) between ItemProcess 'P1' and 'P2' according to the same ItemID, same ItemNo and same ItemLocation. I have around 75000 and it took more then 25 minute to get the width differences for all the ItemId. I tried to use Group by for the width different calculation but it would return multiple row instead of just a value which then would return error. By the way I am use MS SQL server 2008 and #tempcalctbl is a table that I declared in a store procedure.
Does the following help? INSERT INTO #tempcalctbl SELECT P1.SubId , P1.ItemLocation , P1.ItemNo , ABS(P1.Width - P2.Width) * 1000 AS Width , P1.Unit , P1.date FROM #temptbl AS P1 INNER JOIN #temptbl AS P2 ON P1.ItemId = P2.ItemId AND P1.ItemNo = P2.ItemNo AND P1.ItemLocation = P2.ItemLocation WHERE P1.ItemProcess = 'P1' AND P2.ItemProcess = 'P2' EDIT To make use of indexes, you will need to change your table variable to a temporary table CREATE TABLE #temptbl ( ItemId varchar(50), ItemLocation varchar(50), ItemNo varchar(50), Width real, Unit varchar(50), date DATETIME, ItemProcess INT, SubId INT ) CREATE NONCLUSTERED INDEX Index01 ON #temptbl ( ItemProcess ASC, ItemId ASC, ItemLocation ASC, ItemNo ASC ) INCLUDE ( SubId,Width,Unit,date) GO That should speed you up a little.
John Petrak's answer is the best query for this case. If the speed is still now acceptable, maybe you can store #temptbl at a temporary real table, and create the related index on those four columns.
SQL Select Best practice
The following works, I'm just wondering if this is the correct approach to finding the latest value for each audit field. USE tempdb CREATE Table Tbl( TblID Int, AuditFieldID Int, AuditValue Int, AuditDate Date ) GO INSERT INTO Tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(1,10,101,'1/1/2001') INSERT INTO Tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(2,10,102,'1/1/2002') INSERT INTO Tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(3,20,201,'1/1/2001') INSERT INTO Tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(4,20,202,'1/1/2009') SELECT AuditFieldID,AuditValue,AuditDate FROM Tbl A WHERE TblID= (SELECT TOP 1 TblID FROM Tbl WHERE AuditFieldID=A.AuditFieldID ORDER BY AuditDate DESC )
Aggregate/ranking to get key and latest date, join back to get value. This assumes SQL Server 2005+ DECLARE #tbl Table ( TblID Int, AuditFieldID Int, AuditValue Int, AuditDate Date ) INSERT INTO #tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(1,10,101,'1/1/2001') INSERT INTO #tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(2,10,102,'1/1/2002') INSERT INTO #tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(3,20,201,'1/1/2001') INSERT INTO #tbl(TblID,AuditFieldID,AuditValue,AuditDate) VALUES(4,20,202,'1/1/2009') ;WITH cLatest AS ( SELECT ROW_NUMBER() OVER (PARTITION BY AuditFieldID ORDER BY AuditDate DESC) AS Ranking, AuditFieldID, AuditDate FROM #tbl ) SELECT A.AuditFieldID, A.AuditValue, A.AuditDate FROM #tbl A JOIN cLatest C ON A.AuditFieldID = C.AuditFieldID AND A.AuditDate = C.AuditDate WHERE C.Ranking = 1
Simpler: SELECT top 1 AuditFieldID,AuditValue,AuditDate FROM Tbl order by AuditDate DES
There are various methods for doing this. Different methods perform differently. I encourage you to look at this blog which explains the various methods. Including an Aggregated Column's Related Values
you don't need the where statement as you are already selecting from tbl A AND selecting on the same field.