Find MAX value in two columns simultaneously in SQL table - sql

Can somebody help?
I have this table (simplified view, it has 20 columns and more then 1 mln rows)
date_id period_time PlotsID dateOfContractID
20071225 1:12:45 212 a12f
20080812 1:12:45 212 a12f
20080815 10:07:46 232 f45j
20100213 8:05:12 435 y54g
20100213 8:06:33 435 y54g
And I need to find all data with MAX date_id and MAX period_time, grouped by PlotsID
And it must be this
date_id period_time PlotsID dateOfContractID
20080812 1:12:45 212 a12f
20080815 10:07:46 232 f45j
20100213 8:06:33 435 y54g
Using this code, I found MAX date_id and it's working correct, but I need after Max date find MAx Period_time, OR find in one step
SELECT
[date_id],
[period_time],
[PlotsID],
[FieldID],
[partnerContract],
[ownerContractID],
[partnerContractCode]
FROM
bd
WHERE
EXISTS(
SELECT
1 AS Expr1
FROM
bd AS t2
WHERE
partnerContractCode = bd.partnerContractCode
GROUP BY
partnerContractCode
HAVING
( bd.date_id = MAX(date_id) )
)
) AS t1
Create TABLE
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE bd
( [hash_diff] [varbinary](8000) NOT NULL,
[hash_key] [varbinary](8000) NULL,
[date_id] [int] NULL,
[period_time] [time](7) NULL,
[PlotsID] [bigint] NULL,
[FieldID] [bigint] NULL,
[partnerContract] [nvarchar](100) NULL,
[ownerContractID] [bigint] NULL,
[partnerContractCode] [nvarchar](50) NULL,
)
WITH
(
DISTRIBUTION = HASH ( [hash_key] ),
CLUSTERED INDEX
(
[date_id] ASC
)
)
GO

Try this
DECLARE #tbl_SampleData AS TABLE ( date_id DATE, period_time varchar(8), plotsID INT, dateOfContractID VARCHAR(10))
INSERT INTO #tbl_SampleData (date_id , period_time , plotsID , dateOfContractID )
VALUES
('20071225', '1:12:45', 212, 'a12f'),
('20080812', '1:12:45', 212, 'a12f'),
('20080815', '10:07:46', 232, 'f45j'),
('20100213', '8:05:12', 435, 'y54g'),
('20100213', '8:06:33', 435, 'y54g')
--SELECT * FROM #tbl_SampleData
SELECT date_id, period_time, plotsID, dateOfContractID FROM
(
SELECT date_id, period_time, plotsID, dateOfContractID ,
ROW_NUMBER() OVER(PARTITION BY PlotsID ORDER BY date_id DESC, period_time DESC) AS RowID
FROM #tbl_SampleData
) AS a
WHERE RowID = 1

Related

Merging queries

I have two queries that work great but I need to merge the two results and have so far been unable to. It is almost as if I need to pivot the secondary results but it goes way above my knowledge.
The first query gathers all the details (many columns have been omitted for brevity). The second grabs alternate bill codes to be filled into any NULL or EMPTY MisCptID fields if an alternate code is available.
So if MisCptID_01 and MisCptID_02 have data they are left as is but then 3 - 6 need to use the available list of CPTs from the alternate ones. If there are no alternate ones then they stay NULL or EMPTY.
Results from first query (Sample):
ID Location MisCptID_01 MisCptID_02 MisCptID_03 MisCptID_04 MisCptID_05 MisCptID_06
AXXXXXXXX9443 OXXXXXOR 43248 43239 NULL NULL NULL NULL
AXXXXXXXX1163 EXXXXXED 43249 43247 43239 NULL NULL NULL
AXXXXXXXX1765 OXXXXXOR 43251 45385 45382 45384 45380 45381
Results from second Query containing alternate codes (Sample):
ID AlternateCodeCode StandardAmount
AXXXXXXXX9443 80048 49.00
AXXXXXXXX9443 81001 38.00
AXXXXXXXX9443 76000 0.00
AXXXXXXXX1163 84703 80.50
AXXXXXXXX1163 82040 21.70
AXXXXXXXX1163 83036 49.00
AXXXXXXXX1163 85014 10.90
AXXXXXXXX1163 85018 10.90
AXXXXXXXX1163 86901 18.10
AXXXXXXXX1765 88305 185.00
AXXXXXXXX1765 88311 32.00
AXXXXXXXX1765 93005 125.00
AXXXXXXXX1765 80048 49.00
AXXXXXXXX1765 85027 10.80
Desired Results for merging the query results:
ID Location MisCptID_01 MisCptID_02 MisCptID_03 MisCptID_04 MisCptID_05 MisCptID_06
AXXXXXXXX9443 OXXXXXOR 43248 43239 80048 81001 76000 NULL
AXXXXXXXX1163 EXXXXXED 43249 43247 43239 84703 83036 86901
AXXXXXXXX1765 OXXXXXOR 43251 45385 45382 45384 45380 45381
You can unpivot the first query, union the results with the second query and then pivot them back again, like this:
-- sample data:
DECLARE #ResultsOfFirstQuery TABLE (
ID VARCHAR(20) NOT NULL,
Location VARCHAR(10) NOT NULL,
MisCptID_01 INT NULL,
MisCptID_02 INT NULL,
MisCptID_03 INT NULL,
MisCptID_04 INT NULL,
MisCptID_05 INT NULL,
MisCptID_06 INT NULL
)
INSERT INTO #ResultsOfFirstQuery (ID, Location, MisCptID_01, MisCptID_02, MisCptID_03, MisCptID_04, MisCptID_05, MisCptID_06) VALUES
('AXXXXXXXX9443','OXXXXXOR',43248,43239,NULL ,NULL ,NULL ,NULL ),
('AXXXXXXXX1163','EXXXXXED',43249,43247,43239,NULL ,NULL ,NULL ),
('AXXXXXXXX1765','OXXXXXOR',43251,45385,45382,45384,45380,45381)
DECLARE #ResultsOfSecondQuery TABLE (
ID VARCHAR(20) NOT NULL,
AlternateCodeCode INT NOT NULL,
StandardAmount NUMERIC(10,2) NOT NULL
)
INSERT INTO #ResultsOfSecondQuery (ID, AlternateCodeCode, StandardAmount) VALUES
('AXXXXXXXX9443',80048,49.00 ),
('AXXXXXXXX9443',81001,38.00 ),
('AXXXXXXXX9443',76000,0.00 ),
('AXXXXXXXX1163',84703,80.50 ),
('AXXXXXXXX1163',82040,21.70 ),
('AXXXXXXXX1163',83036,49.00 ),
('AXXXXXXXX1163',85014,10.90 ),
('AXXXXXXXX1163',85018,10.90 ),
('AXXXXXXXX1163',86901,18.10 ),
('AXXXXXXXX1765',88305,185.00),
('AXXXXXXXX1765',88311,32.00 ),
('AXXXXXXXX1765',93005,125.00),
('AXXXXXXXX1765',80048,49.00 ),
('AXXXXXXXX1765',85027,10.80 )
-- query:
SELECT p.ID, q1.Location, p.[1] AS MisCptID_01, p.[2] AS MisCptID_02, p.[3] AS MisCptID_03, p.[4] AS MisCptID_04, p.[5] AS MisCptID_05, p.[6] AS MisCptID_06
FROM (
SELECT x.ID, x.Code, ROW_NUMBER() OVER (PARTITION BY x.ID ORDER BY x.SourceQuery, x.Position) AS Position
FROM (
SELECT u.ID, u.Code, 1 AS SourceQuery, RIGHT(u.ColumnName,2) AS Position
FROM (
SELECT ID, MisCptID_01, MisCptID_02, MisCptID_03, MisCptID_04, MisCptID_05, MisCptID_06
FROM #ResultsOfFirstQuery
) q
UNPIVOT (Code FOR ColumnName IN (MisCptID_01, MisCptID_02, MisCptID_03, MisCptID_04, MisCptID_05, MisCptID_06)) u
UNION ALL
SELECT ID, AlternateCodeCode, 2 AS SourceQuery, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS Position
FROM #ResultsOfSecondQuery
) x
) y
PIVOT (MAX(Code) FOR Position IN ([1],[2],[3],[4],[5],[6])) p
INNER JOIN #ResultsOfFirstQuery q1 ON q1.ID = p.ID

Calculate date difference between dates in different rows of a dataset

A table looks like this :
CREATE TABLE [dbo].[HistDT](
[ID] [bigint] NULL,
[StartDtSK] [varchar](8) NULL,
[StartDt] [datetime] NULL,
[status] [nvarchar](30) NULL,
) ON [PRIMARY]
Example data set:
ID | StartDtSK | StartDt | Status |
1 20190520 20-05-2019 12:00:13 10
1 20190520 20-05-2019 10:00:00 5
1 20190414 14-04-2019 13:23:00 2
2 20190312 12-03-2019 10:03:00 10
2 20190308 08-03-2019 18:03:00 1
etc..
I need a query which will display the number of days spent in each status. That would be easy if the table i inherited had an end date. I would then calculate the datediff and pivot for column status values.
Maybe i should create a new table using ssis where i will add an EndDt column which will be the StartDt of the latest added Status.
But is there any way to do this without creating another table?
SQL Server 2008
This is not very pretty, and I haven't tested it for all use cases. I hope you can use it or find inspiration. I'm sure there is a better way :)
declare #table2 table (
[ID] [bigint] NULL,
[StartDtSK] [varchar](8) NULL,
[StartDt] [datetime] NULL,
[status] [nvarchar](30) NULL
)
insert into #table2
values
(1 , '20190520','2019-05-20 12:00:13','10'),
(1 , '20190520','2019-05-20 10:00:00','5'),
(1 , '20190414','2019-04-14 13:23:00','2'),
(2, '20190312', '2019-03-12 10:03:00', '10'),
(2 , '20190308', '2019-03-08 18:03:00', '1')
select *,DATEDIFF(dd,startdt,enddate) as TotalDAys from (
select x.ID,StartDtSK,Startdt,[Status],Enddate from (
select *,ROW_NUMBER() over(partition by id order by startdt) as rn from #table2
) x
cross apply ( select * from (select id,StartDt as Enddate,ROW_NUMBER() over(partition by id order by startdt) as rn2 from #table2 b
)f where (rn +1 = f.rn2 ) and x.id = f.id ) d
union all
select ID,StartDtSK,startdt,[Status],'9999-12-31' as Enddate from (
select *,ROW_NUMBER() over(partition by id order by startdt desc) as rn from #table2
)X where rn=1
)y
order by id,startdt
SQL Server 2008 without cross apply
This might be a bit more pretty :)
select *,DATEDIFF(dd,startdt,enddate) as TotalDAys from (
select x.ID,StartDtSK,Startdt,[Status],case when Enddate is null then '9999-12-31' else Enddate end as Enddate from (
select *,ROW_NUMBER() over(partition by id order by startdt) as rn from #table2
) x
left join (
select * from (select id,StartDt as Enddate,ROW_NUMBER() over(partition by id order by startdt) as rn2 from #table2 b
)f ) d on (rn +1 = d.rn2 ) and x.id = d.id
)y
SQL Server 2012 and above:
Is this what you want?
declare #table2 table (
[ID] [bigint] NULL,
[StartDtSK] [varchar](8) NULL,
[StartDt] [datetime] NULL,
[status] [nvarchar](30) NULL
)
insert into #table2
values
(1 , '20190520','2019-05-20 12:00:13','10'),
(1 , '20190520','2019-05-20 10:00:00','5'),
(1 , '20190414','2019-04-14 13:23:00','2')
select *,Datediff(dd,Startdt,Enddate) as TotalDays from (
select *,LAG(StartDt,1,'9999-12-31') over(partition by ID order by StartDT desc) as EndDate from #table2
)x
Insert a rule that handles current status (9999-12-31) date
Maybe LEAD function is usefull for your question.
Like this
IsNull(DateAdd(SECOND,-1,Cast(LEAD ([StartDt],1) OVER (PARTITION BY [status] ORDER BY [StartDt]) AS DATETIME)),getdate()) AS EndDate

Calc SUM total of pivoted table by two columns into predefined table?

Big thanks to #JohnCappelletti as he's shown how to pivot a table:
DECLARE #OperatorPrice TABLE (ID INT NOT NULL, OperatorId INT NULL, Price
NUMERIC(18,3) NULL, FName VARCHAR(50) NULL)
INSERT INTO #OperatorPrice (
ID, OperatorId, Price, FName
)
VALUES
(226, 996, 22954,'Operator1')
, (266, 1016, 79011.2, 'Operator3')
, (112, 1029, 14869, 'Operator4')
, (112, 996, 22954, 'Operator1')
, (93, 1031, 10568.96, 'Operator5')
DECLARE #TR TABLE
(
ID INT NULL ,
Operator1 DECIMAL(18,3) NULL, OC1 DECIMAL(18,3) NULL, Operator2 DECIMAL(18,3) NULL,
OC2 DECIMAL(18,3) NULL, Operator3 DECIMAL(18,3) NULL, OC3 DECIMAL(18,3) NULL,
Operator4 DECIMAL(18,3) NULL, OC4 DECIMAL(18,3) NULL, Operator5 DECIMAL(18,3) NULL,
OC5 DECIMAL(18,3) NULL
)
INSERT #TR
SELECT *
FROM (
Select A.ID
,B.*
From #OperatorPrice A
Cross Apply ( values (FName,Price)
,('OC'+replace(FName,'Operator',''),OperatorID)
) B (Item,Value)
Union All
Select ID=(select min(ID) From #OperatorPrice)
,B.*
From ( Select Top 50 N=Row_Number() Over (Order By (Select NULL))
From master..spt_values n1 ) A
Cross Apply ( values (concat('Operator',N),NULL)
,(concat('OC',N),NULL)
) B (Item,Value)
) AS SourceTable
PIVOT ( sum(Value) FOR Item IN (Operator1, OC1, Operator2, OC2,
Operator3, OC3, Operator4, OC4, Operator5, OC5) ) AS PivotTable
The above code works perfectly!
However, I would like the total sum for each column. So the desired ouput should looks like this:
ID Operator1 OC1 Operator2 OC2 Operator3 OC3 Operator4 OC4 Operator5 OC5
Total 45908.000 1992 NULL NULL NULL NULL NULL NULL NULL NULL
93 NULL NULL NULL NULL NULL NULL NULL NULL 10568.96 1031
112 22954.000 996.0 NULL NULL NULL NULL 14869.0 1029.000 NULL NULL
226 22954.000 996.0 NULL NULL NULL NULL 14869.0 1029.000 NULL NULL
266 NULL NULL NULL NULL 79011.200 1016.000 NULL NULL NULL NULL
or an image:
I've tried to use the following code:
INSERT #TR
SELECT
Total = SUM([Operator1] + [OC1] + [Operator2] + [OC2] + [Operator3] +
[OC3]+ [Operator4] + [OC4] + [Operator5] + [OC5])
, *
FROM (
Select A.ID
,B.*
From #OperatorPrice A
Cross Apply ( values (FName,Price)
,('OC'+replace(FName,'Operator',''),OperatorID)
) B (Item,Value)
Union All
Select ID=(select min(ID) From #OperatorPrice)
,B.*
From ( Select Top 50 N=Row_Number() Over (Order By (Select NULL)) From
master..spt_values n1 ) A
Cross Apply ( values (concat('Operator',N),NULL)
,(concat('OC',N),NULL)
) B (Item,Value)
) AS SourceTable
PIVOT ( sum(Value) FOR Item IN (Operator1, OC1, Operator2, OC2,
Operator3, OC3, Operator4, OC4, Operator5, OC5) ) AS PivotTable
But it doesn't work as it shows an error:
Msg 8120, Level 16, State 1, Line 24 Column 'PivotTable.ID' is
invalid in the select list because it is not contained in either an
aggregate function or the GROUP BY clause.
How can I get SUM of each column and put this row at the first place?
Notice
The ID in #TR is now a varchar(25)
Added two "TOTAL" rows in the CROSS APPLY
After the Union All, I changed the ID to "Total"
.
DECLARE #OperatorPrice TABLE (ID int NOT NULL, OperatorId INT NULL, Price
NUMERIC(18,3) NULL, FName VARCHAR(50) NULL)
INSERT INTO #OperatorPrice (
ID, OperatorId, Price, FName
)
VALUES
(226, 996, 22954,'Operator1')
, (266, 1016, 79011.2, 'Operator3')
, (112, 1029, 14869, 'Operator4')
, (112, 996, 22954, 'Operator1')
, (93, 1031, 10568.96, 'Operator5')
DECLARE #TR TABLE
(
ID varchar(25) NULL ,
Operator1 DECIMAL(18,3) NULL, OC1 DECIMAL(18,3) NULL, Operator2 DECIMAL(18,3) NULL,
OC2 DECIMAL(18,3) NULL, Operator3 DECIMAL(18,3) NULL, OC3 DECIMAL(18,3) NULL,
Operator4 DECIMAL(18,3) NULL, OC4 DECIMAL(18,3) NULL, Operator5 DECIMAL(18,3) NULL,
OC5 DECIMAL(18,3) NULL
)
INSERT #TR
SELECT *
FROM (
Select B.*
From #OperatorPrice A
Cross Apply ( values ('Total',FName,Price)
,('Total','OC'+replace(FName,'Operator',''),OperatorID)
,(convert(varchar(25),A.ID),FName,Price)
,(convert(varchar(25),A.ID),'OC'+replace(FName,'Operator',''),OperatorID)
) B (ID,Item,Value)
Union All
Select ID='Total'
,B.*
From ( Select Top 50 N=Row_Number() Over (Order By (Select NULL))
From master..spt_values n1 ) A
Cross Apply ( values (concat('Operator',N),NULL)
,(concat('OC',N),NULL)
) B (Item,Value)
) AS SourceTable
PIVOT ( sum(Value) FOR Item IN (Operator1, OC1, Operator2, OC2,
Operator3, OC3, Operator4, OC4, Operator5, OC5) ) AS PivotTable
Select * from #TR
Order by try_convert(int,ID)
Returns
You can use CTE to carry your pivot result set. UNION ALL combine SUM total result set and pivot result.
;with cte as (
SELECT *
FROM (
Select A.ID
,B.*
From #OperatorPrice A
Cross Apply ( values (FName,Price)
,('OC'+replace(FName,'Operator',''),OperatorID)
) B (Item,Value)
Union All
Select ID=(select min(ID) From #OperatorPrice)
,B.*
From ( Select Top 50 N=Row_Number() Over (Order By (Select NULL))
From master..spt_values n1 ) A
Cross Apply ( values (concat('Operator',N),NULL)
,(concat('OC',N),NULL)
) B (Item,Value)
) AS SourceTable
PIVOT ( sum(Value) FOR Item IN (Operator1, OC1, Operator2, OC2,
Operator3, OC3, Operator4, OC4, Operator5, OC5) ) AS PivotTable
)
INSERT #TR
SELECT
NULL,
SUM(Operator1),
SUM(OC1),
SUM(Operator2),
SUM(OC2),
SUM(Operator3),
SUM(OC3),
SUM(Operator4),
SUM(OC4),
SUM(Operator5),
SUM(OC5)
FROM CTE
UNION ALL
SELECT ID,Operator1,OC1,Operator2,OC2,Operator3,OC3,Operator4,OC4,Operator5,OC5
FROM cte
sqlfiddle

SQL Server SQL Statement - Updating record

I have a data as below:
I need to update Matching_id and Matching_Type by using column id, region, company, dept, subdept and amountsepend. The logic is:
Sum AmountSepend by Region, Company, Dept and SubDept. If the sum amount is 0 then Matching_Type is 'Match' and Matching_id is the combination of the id for the matched record else 'Not Match' and Matching_id is the id. **SUM means the total sum of all records for same criteria regardless the AmountSepend is positive or negative.
Another important criteria is if the transaction is single record, meaning the total count by grouping by Region, Company, Dept and SubDept is 1 then Matching type is Not Match and Matching_UID is id regardless the AmountSepend is 0 or positive/negative value. Example id 8.
Below is the output:
Here the table and data script
CREATE TABLE [dbo].[StackoverflowQuest](
[id] [int] NOT NULL,
[Region] [varchar](50) NULL,
[Company] [varchar](50) NULL,
[Dept] [varchar](50) NULL,
[SubDept] [varchar](50) NULL,
[AmountSepend] [float] NULL,
[Matching_id] [varchar](100) NULL,
[Matching_Type] [varchar](100) NULL
) ON [PRIMARY]
How could I achieved such result ? Any help/hint would be appreciate
CREATE TABLE #Table(Id INT,Region VARCHAR(100),Company INT,Dept INT,SubDept
INT,AmtSpend INT,MatchingId VARCHAR(100),MatchingType VARCHAR(100))
INSERT INTO #Table(Id ,Region ,Company , Dept ,SubDept ,AmtSpend )
SELECT 1,'NAM',12378,1,NULL,900 UNION ALL
SELECT 2,'NAM',12378,1,NULL,-900 UNION ALL
SELECT 3,'NAM',12370,1,23,1000 UNION ALL
SELECT 4,'ASA',1234,9,12,5000 UNION ALL
SELECT 5,'NAM',12370,1,23,-1000 UNION ALL
SELECT 6,'ASA',1234,9,12,800 UNION ALL
SELECT 7,'ASA',1234,9,12,-600 UNION ALL
SELECT 8,'ASA',12311,6,NULL,200
UPDATE #Table SET MatchingId = MatchIds,MatchingType = 'Match'
FROM
(
SELECT T2.Company,STUFF( ( SELECT ',' + CAST(T3.Id AS VARCHAR) FROM #Table
T3 WHERE T2.Company = T3.Company FOR XML PATH('')),1,1,'') MatchIds
FROM #Table T2
JOIN
(
SELECT T1.Company Company,SUM(T1.AmtSpend) Total
FROM #Table T1
GROUP BY T1.Company
HAVING SUM(T1.AmtSpend) = 0
)A ON A.Company = T2.Company
GROUP BY T2.Company
) A
WHERE A.Company = #Table.Company
UPDATE #Table SET MatchingId = CAST(Id AS VARCHAR),MatchingType = 'Not
Match' WHERE ISNULL(MatchingId,'') = ''
SELECT * FROM #Table

SQL Query get data from one table, and get data from only one row from another table

I don't know how to explain my problem in the title, so I'll explain it better here...
I have two tables
CREATE TABLE [dbo].[Ventas]
(
[IdVenta] [int] IDENTITY(1,1) NOT NULL,
[FechaVenta] [date] NULL,
[HoraVenta] [varchar](10) NULL,
[Subtotal] [money] NULL,
[Iva] [money] NULL,
[Total] [money] NULL,
[Saldo] [money] NULL,
[Abono] [money] NULL,
[FormaDePago] [varchar](50) NULL,
[Plazos] [int] NULL,
[Estado] [varchar](50) NULL,
)
CREATE TABLE [dbo].[Plazos]
(
[IdPlazo] [int] IDENTITY(1,1) NOT NULL,
[IdVenta] [int] NULL,
[NumeroPlazo] [int] NULL,
[FechaVencimiento] [date] NULL,
[FechaCorte] [date] NULL,
[FechaPenalizacion] [date] NULL,
[FechaLiquidacion] [date] NULL,
[Total] [money] NULL,
[Cargo] [money] NULL,
[Abono] [money] NULL,
[Estado] [varchar](50) NULL,
)
now to add some data
INSERT [dbo].[Ventas] ([IdVenta], [FechaVenta], [HoraVenta], [Subtotal], [Iva], [Total], [Saldo], [Abono], [FormaDePago], [Plazos], [Estado]) VALUES (182, CAST(0x54360B00 AS Date), N'11:20', 500.0000, 55.0000, 555.0000, 333.0000, 222.0000, N'A Credito', 5, N'Pendiente De Pago')
INSERT [dbo].[Ventas] ([IdVenta], [FechaVenta], [HoraVenta], [Subtotal], [Iva], [Total], [Saldo], [Abono], [FormaDePago], [Plazos], [Estado]) VALUES (183, CAST(0x54360B00 AS Date), N'12:29', 575.0000, 63.2500, 638.2500, 638.2500, 0.0000, N'Una Sola Exhibicion', 1, N'Pendiente De Pago')
INSERT [dbo].[Plazos] ([IdPlazo], [IdVenta], [NumeroPlazo], [FechaVencimiento], [FechaCorte], [FechaPenalizacion], [FechaLiquidacion], [Total], [Cargo], [Abono], [Estado]) VALUES (93, 182, 1, CAST(0x54360B00 AS Date), CAST(0x57360B00 AS Date), CAST(0x5C360B00 AS Date), CAST(0x54360B00 AS Date), 111.0000, 0.0000, 111.0000, N'Liquidado')
INSERT [dbo].[Plazos] ([IdPlazo], [IdVenta], [NumeroPlazo], [FechaVencimiento], [FechaCorte], [FechaPenalizacion], [FechaLiquidacion], [Total], [Cargo], [Abono], [Estado]) VALUES (94, 182, 2, CAST(0x73360B00 AS Date), CAST(0x75360B00 AS Date), CAST(0x7A360B00 AS Date), CAST(0x54360B00 AS Date), 111.0000, 0.0000, 111.0000, N'Liquidado')
INSERT [dbo].[Plazos] ([IdPlazo], [IdVenta], [NumeroPlazo], [FechaVencimiento], [FechaCorte], [FechaPenalizacion], [FechaLiquidacion], [Total], [Cargo], [Abono], [Estado]) VALUES (95, 182, 3, CAST(0x91360B00 AS Date), CAST(0x94360B00 AS Date), CAST(0x99360B00 AS Date), NULL, 111.0000, 111.0000, 0.0000, N'Pendiente')
INSERT [dbo].[Plazos] ([IdPlazo], [IdVenta], [NumeroPlazo], [FechaVencimiento], [FechaCorte], [FechaPenalizacion], [FechaLiquidacion], [Total], [Cargo], [Abono], [Estado]) VALUES (96, 183, 1, CAST(0x54360B00 AS Date), CAST(0x57360B00 AS Date), CAST(0x5C360B00 AS Date), NULL, 639.0000, 639.0000, 0.0000, N'Pendiente')
Foreign Key On Ventas.IdVenta = Plazos.IdVenta
Ok, Here's the deal...
I need to use a query that brings data from all sales (Ventas), which only it supposed to be 2 rows...
However, I need data from Plazos, but I only need data from Plazos
What I need is to display data from plazos on the same row as Ventas, but only data from the most recent Plazo...
you may notice that for example, in Plazos there is a column called NumeroPlazo which increases on the same IdVenta... what I need in this example is to display:
Ventas IdVenta 182 with data from Plazos IdPlazo 95 (since from Plazos, IdPlazo 95 has the highest number on the column Numero Plazos...
and of course IdVenta 183, but since it only has one Plazo, it will display data from that plazo...
At the moment I had this query...
SELECT Ventas.*, Plazos.*,
FROM Ventas INNER JOIN Plazos ON Plazos.IdVenta = Ventas.IdVenta
WHERE Ventas.Estado = 'Pendiente De Pago'
ORDER BY Ventas.FechaVenta DESC, Ventas.HoraVenta DESC
but it returns 4 rows (3 rows for Venta where IdVenta = 182, and one where IdVenta = 183)
What I want is only 2 rows...
Then I tried this query that worked... but only for one row
SELECT Ventas.*, Plazos.*,
FROM Ventas INNER JOIN Plazos ON Plazos.IdVenta = Ventas.IdVenta
WHERE Ventas.Estado = 'Pendiente De Pago'
AND Plazos.NumeroPlazo = (SELECT MAX(Plazos.NumeroPlazo) FROM Plazos WHERE Plazos.IdVenta = 182)
ORDER BY Ventas.FechaVenta DESC, Ventas.HoraVenta DESC
Obviously it only works for one sale since I specify Plazos.IdVenta = 182...
My question here is... how can I use the latter query to get the data I want for each sale...
I hope yuo can help me...
If you need me to be more specific, please let me know.
Thanks in advance
You can use CROSS APPLY which allows you to run a subquery per-each-row of the preceding tables in the FROM list.
SELECT Ventas.*, Plazos.*
FROM Ventas
cross apply (
select TOP(1) *
from Plazos
WhERE Plazos.IdVenta = Ventas.IdVenta
ORDER BY [NumeroPlazo] DESC) Plazos
WHERE Ventas.Estado = 'Pendiente De Pago'
ORDER BY Ventas.FechaVenta DESC, Ventas.HoraVenta DESC
Doing it via Row_Number() is probably faster, but here the subquery will require you to alias all the columns at the inner level, which is probably not a bad idea anyway.
SELECT *
FROM
(
SELECT
v.[IdVenta], v.[FechaVenta], v.[HoraVenta], v.[Subtotal], v.[Iva], v.[Total], v.[Saldo], v.[Abono], v.[FormaDePago], v.[Plazos], v.[Estado],
p.[IdPlazo], p.[NumeroPlazo], p.[FechaVencimiento], p.[FechaCorte], p.[FechaPenalizacion], p.[FechaLiquidacion], p.[Total] plazostotal, p.[Cargo], p.[Abono] plazasabono, p.[Estado] plazosestado,
RowN = ROW_NUMBER() over (partition by v.[IdVenta] order by p.[NumeroPlazo] desc)
FROM Ventas v
JOIN Plazos p ON p.IdVenta = v.IdVenta
WHERE v.Estado = 'Pendiente De Pago'
) X
WHERE RowN = 1
ORDER BY FechaVenta DESC, HoraVenta DESC
It is simple. In your second question replace 182 on Ventas.IdVenta
SELECT Ventas.*, Plazos.*
FROM Ventas INNER JOIN Plazos ON Plazos.IdVenta = Ventas.IdVenta
WHERE Ventas.Estado = 'Pendiente De Pago'
AND Plazos.NumeroPlazo = (SELECT MAX(Plazos.NumeroPlazo) FROM Plazos WHERE Plazos.IdVenta = Ventas.IdVenta)
ORDER BY Ventas.FechaVenta DESC, Ventas.HoraVenta DESC