I am in need to some help writing a SQL 2012 query that will help me find and mark orderID's that are a $0.00 payments due to reversal(s)
So far I have:
Select Distinct a.orderID, a.orderPaid,
(Select SUM((c1.linePrice + c1.lineShippingCost + c1.lineTaxCost + c1.lineOptionCost) * c1.lineQuantity)
From vwSelectOrderLineItems c1 Where c1.orderID = a.orderID) As OrderAmount,
(Select SUM(b1.payAmount) FROM vwSelectOrderPayments b1 Where b1.orderID = a.orderID) as Payment,
1 As IsReversal
From vwSelectOrders a
Left Outer Join vwSelectOrderPayments b On b.orderID = a.orderID
Where b.payValid = 1 AND a.orderPaid = 0
Which is returning me some $0 payments on some orders. When I query that payment table with the orderID of these records, I can see that 2 payments were posted... 1 the original payment, 2 the reversal.
How Can I flag the Orders that are $0 payments?
Oders
CREATE TABLE [dbo].[TblOrders](
[orderID] [bigint] IDENTITY(1000,1) NOT NULL,
[orderPaid] [bit] NOT NULL,
[orderPaidOn] [datetime] NULL
CONSTRAINT [PK_TblOrders] PRIMARY KEY CLUSTERED
(
[orderID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 50) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[TblOrders] ADD CONSTRAINT [DF__TblOrders__order__1975C517] DEFAULT ((0)) FOR [orderPaid]
Order Line Items
CREATE TABLE [dbo].[TblOrderLineItems](
[lineID] [bigint] IDENTITY(1,1) NOT NULL,
[orderID] [bigint] NOT NULL,
[lineQuantity] [int] NOT NULL,
[linePrice] [money] NOT NULL,
[lineShippingCost] [money] NOT NULL,
[lineTaxCost] [money] NOT NULL,
[lineOptionCost] [money] NOT NULL,
CONSTRAINT [PK_TblOrderLineItems] PRIMARY KEY CLUSTERED
(
[lineID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 50) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[TblOrderLineItems] ADD CONSTRAINT [DF_TblOrderLineItems_lineShippingCost] DEFAULT ((0)) FOR [lineShippingCost]
GO
ALTER TABLE [dbo].[TblOrderLineItems] ADD CONSTRAINT [DF_TblOrderLineItems_lineTaxCost] DEFAULT ((0)) FOR [lineTaxCost]
GO
ALTER TABLE [dbo].[TblOrderLineItems] ADD CONSTRAINT [DF_TblOrderLineItems_lineOptionCost] DEFAULT ((0)) FOR [lineOptionCost]
GO
Order Payments
CREATE TABLE [dbo].[TblOrderPayments](
[paymentID] [bigint] IDENTITY(1,1) NOT NULL,
[orderID] [bigint] NOT NULL,
[payAmount] [money] NOT NULL,
[payPosted] [datetime] NOT NULL,
[payValid] [bit] NOT NULL,
CONSTRAINT [PK_TblOrderPayments] PRIMARY KEY CLUSTERED
(
[paymentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 50) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[TblOrderPayments] ADD CONSTRAINT [DF_TblOrderPayments_payValid] DEFAULT ((0)) FOR [payValid]
GO
Views
CREATE VIEW [dbo].[vwSelectOrderLineItems] AS
SELECT linePrice, lineShippingCost, lineTaxCost, lineOptionCost, lineQuantity
FROM [dbo].[TblOrderLineItems]
CREATE VIEW [dbo].[vwSelectOrderPayments] AS
SELECT paymentID, orderID, payAmount, payValid
FROM dbo.TblOrderPayments
CREATE VIEW [dbo].[vwSelectOrders] AS
SELECT orderID , orderPaid
FROM dbo.TblOrders
Note
I cannot change the table structure
SELECT distinct a.orderid,
a.orderPaid,
c.OrderAmount
d.Payment
From vwSelectOrders AS a
INNER JOIN ( Select SUM((linePrice + lineShippingCost + lineTaxCost + lineOptionCost) * lineQuantity) As orderAmount,OrderID
From vwSelectOrderLineItems group by orderid) AS C on c.orderID = a.orderID
INNER JOIN (Select SUM(payAmount) as Payment,orderID FROM vwSelectOrderPayments WHERE isnull(SUM(PayAmount),0) > 0 GROUP BY OrderID) AS d ON d.orderID = a.orderID
Left Outer Join vwSelectOrderPayments b On b.orderID = a.orderID
Where b.payValid = 1 AND a.orderPaid = 0 AND
This is a better query as you do not have to us a correlated subquery. Correlated queries are when a subquery references an outerquery row. This isn't optimal because every row the outerquery runs the correlated subquery will execute. Once you give us table definitions we can probably fix the overall data return of your query.
Related
I'm trying to join data from 3 tables in SQL Servre and display in result:
Alias of an entity
if the entity is virtual
the last date (if known)
the value (if known)
I tried this :
select
sr.alias, c.virtual, max(d.date) date
from
App_references sr
join
Sensor c on (c.id_capteur = sr.id_capteur)
left join
Sensor_data d on (c.id_capteur = d.id_capteur)
group by
d.id_capteur, sr.alias, c.virtual
order by
sr.alias
Here is the database scheme:
CREATE TABLE [dbo].[App_reference]
(
[id_ref] [int] IDENTITY(1,1) NOT NULL,
[alias] [varchar](60) NOT NULL,
[id_capteur] [int] NOT NULL,
CONSTRAINT [PK_App_reference] PRIMARY KEY CLUSTERED
(
[id_ref] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Sensor]
(
[id_capteur] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[virtual] [tinyint] NULL,
[unite] [varchar](5) NULL,
[id_type] [int] NOT NULL,
CONSTRAINT [PK_Sensor] PRIMARY KEY CLUSTERED
(
[id_capteur] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[Sensor_data]
(
[id_entry] [int] IDENTITY(1,1) NOT NULL,
[id_capteur] [int] NOT NULL,
[value] [xml] NOT NULL,
[date] [datetime] NOT NULL,
CONSTRAINT [PK_Sensor_data] PRIMARY KEY CLUSTERED
(
[id_entry] ASC,
[id_capteur] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Supposing each columns like "id_%" are linked by foreign key.
The request on top pass well, I got value :
alias virtual date
Place 1 (Physique) 0 2017-04-27 14:58:42.423
Place 2 1 NULL
Place 3 1 NULL
But I tried to select the value too by doing this :
select
sr.alias, c.virtual, max(d.date) date, d.value
from
Citopia_test.dbo.Smartparking_reference sr
join
Citopia_test.dbo.Sensor c on (c.id_capteur = sr.id_capteur)
left join
Citopia_test.dbo.Sensor_data d on (c.id_capteur = d.id_capteur)
group by
d.id_capteur, sr.alias, c.virtual
order by
sr.alias
And I got this error :
Column 'Sensor_data.value' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
So I tried several things like adding column in the group by but nothing changes.
You probably want the value from the record with max date. Use ROW_NUMBER to get those records.
select alias, virtual, date, value
from
(
select
sr.alias, c.virtual, d.date, d.value,
row_number() over (partition by sr.alias order by d.date desc) as rn
from Citopia_test.dbo.Smartparking_reference sr
join Citopia_test.dbo.Sensor c on (c.id_capteur = sr.id_capteur)
left join Citopia_test.dbo.Sensor_data d on (c.id_capteur = d.id_capteur)
) numbered
where rn = 1
order by sr.alias;
This gets you one row per sr.alias. If you want one row per sr.alias + c.virtual then change the partition by clause accordingly.
I have a SQL Server query that is performing poorly when retrieving data via pagination using offset/fetch. The earlier pages return results very fast but later ones are extremely slow and creating a bottleneck in our system. It's joining on two temp tables (#A and #T). Here is a pared down version of the query:
Select
I.CustomerID,
I.InvoiceID,
I.ItemID,
TI1.TrackID as TrackID1,
TI1.ItemName as ItemName1,
TI1.TrackCatID as TrackCatID1,
TI1.CategoryName as CategoryName1,
TI2.TrackID as TrackID2,
TI2.ItemName as ItemName2,
TI2.TrackCatID as TrackCatID2,
TI2.CategoryName as CategoryName2,
A.AccID,
A.Name as AccountName,
A.utimestamp as UpdateTimeStamp
FROM
#A A
Inner Join [dbo].[Item] I WITH(FORCESEEK)
On
A.CustomerID = I.CustomerID And
A.AccountID = I.AccountID
Left Join #T TI1 On
I.CustomerID = TI1.CustomerID And
I.TrackID1 = TI1.TrackID
Left Join #T TI2 On
I.CustomerID = TI2.CustomerID And
I.TrackID2 = TI2.TrackID
Order by
A.utimestamp
Offset 0 Rows Fetch Next 1000 Rows Only
Where the temp tables are defined as:
Create table #T (CustomerID uniqueidentifier, TrackCatID uniqueidentifier, TrackID uniqueidentifier, ItemName varchar(100), CategoryName varchar(100),PRIMARY KEY (CustomerID,TrackID))
Create table #A (CustomerID uniqueidentifier, AccountID uniqueidentifier, Name varchar(100), utimestamp timestamp, PRIMARY KEY (CustomerID, AccountID))
Regarding the DB table [dbo].[Item] it is defined as:
CREATE TABLE [dbo].[Item](
[Sequence] [int] IDENTITY(1,1) NOT NULL,
[CustomerID] [uniqueidentifier] NOT NULL,
[ItemID] [uniqueidentifier] NOT NULL,
[AccountID] [uniqueidentifier] NULL,
[TrackID1] [uniqueidentifier] NULL,
[TrackID2] [uniqueidentifier] NULL,
CONSTRAINT [PK_Item] PRIMARY KEY NONCLUSTERED
(
[CustomerID] ASC,
[ItemID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY],
CONSTRAINT [CX_Item] UNIQUE CLUSTERED
(
[CustomerID] ASC,
[Sequence] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
And has a number of indexes that each have have several columns:
Item Indexes
1: CusotmerID, Sequence
2: CusotmerID, AccountId, Sequence
3: CusotmerID, TrackId1
4: CusotmerID, TrackId2
5: CusotmerID, ItemID
Is there something I'm missing that's causing the later paginated queries to be slow? Note: The 0 in "Offset 0 Rows" increases by 1000 for every page.
Also, I added a index to the temp table #A and didn't see an improvement to the results:
CREATE INDEX IDX_Timestamp ON #A(utimestamp)
I have a table UserInfoComputed whose data comes from UserInfo and UserInfoComputed also have foreign key constraint to UserCompany.
I have a trigger on UserInfo which inserts/updates/deletes rows into UserInfoComputed
Here is my UserInfoComputed table:
CREATE TABLE [dbo].[UserInfoComputed ](
[id] AS (CONVERT([bigint],replace([law_id],'LAW',''),(0))) PERSISTED NOT NULL,
[company_id] [varchar](12) NOT NULL,
[first_name] [varchar](30) NOT NULL,
[last_name] [varchar](30) NOT NULL,
[law_id] [varchar](12) NOT NULL,
[type] [smallint] NULL,
[dtype] AS (case [TYPE] when (1) then 'Corporate' else 'Non-Corporate' end) PERSISTED NOT NULL,
CONSTRAINT [PK_UserInfoComputed] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[UserInfoComputed] WITH CHECK ADD CONSTRAINT [FK668581C04AA07B12] FOREIGN KEY([company_id])
REFERENCES [dbo].[UserCompany] ([id])
GO
Here is my UserInfo table
CREATE TABLE [dbo].[UserInfo](
[ID] [varchar](12) NOT NULL,
[CompanyID] [varchar](12) NULL,
[Status] [char](4) NULL,
[FirstName] [varchar](30) NOT NULL,
[LastName] [varchar](30) NOT NULL,
CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Here is the UserCompany table
CREATE TABLE [dbo].[UserCompany](
[ID] [varchar](12) NOT NULL,
[Name] [varchar](100) NULL,
[ShortName] [varchar](25) NULL,
[Type] [smallint] NULL,
CONSTRAINT [PK_UserCompany] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
The type values are either 1 or 2 or 3
Here is my trigger on UserInfo table
CREATE TRIGGER [dbo].[ReconcileUserInfoComputed]
ON [dbo].[UserInformation]
AFTER INSERT,DELETE,UPDATE
AS
IF ##ROWCOUNT = 0 -- exit trigger when zero records affected
BEGIN
RETURN
END
IF EXISTS (SELECT * FROM INSERTED)
BEGIN
IF EXISTS (SELECT * FROM DELETED)
BEGIN
--UPDATE
UPDATE [dbo].[UserInformationComputed]
SET -- use new values from inserted
first_name = (SELECT FirstName FROM inserted),
last_name = (SELECT LastName FROM inserted),
law_id = (SELECT ID FROM inserted)
WHERE law_id = (SELECT ID FROM deleted)
END
ELSE
BEGIN
--INSERT
INSERT INTO [dbo].[UserInfoComputed] (first_name,last_name, law_id)
SELECT FirstName, LastName, ID FROM inserted
END
END
ELSE IF EXISTS(SELECT * FROM DELETED)
BEGIN
--DELETE
DELETE FROM [dbo].[UserInfoComputed]
WHERE law_id = (SELECT id FROM deleted)
END
GO
Is there a way to insert or update type value from UserCompany into UserInfoComputed table in ReconcileUserInfoComputed trigger?
I wish to migrate some data from a single table into these new THREE tables.
Here's my destination schema:
Notice that I need to insert into the first Location table .. grab the SCOPE_IDENTITY() .. then insert the rows into the Boundary and Country tables.
The SCOPE_IDENTITY() is killing me :( meaning, I can only see a way to do this via CURSORS. Is there a better alternative?
UPDATE
Here's the scripts for the DB Schema....
Location
CREATE TABLE [dbo].[Locations](
[LocationId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[OriginalLocationId] [int] NOT NULL,
CONSTRAINT [PK_Locations] PRIMARY KEY CLUSTERED
(
[LocationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
Country
CREATE TABLE [dbo].[Locations_Country](
[IsoCode] [nchar](2) NOT NULL,
[LocationId] [int] NOT NULL,
CONSTRAINT [PK_Locations_Country] PRIMARY KEY CLUSTERED
(
[LocationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Locations_Country] WITH CHECK ADD CONSTRAINT [FK_Country_inherits_Location] FOREIGN KEY([LocationId])
REFERENCES [dbo].[Locations] ([LocationId])
GO
ALTER TABLE [dbo].[Locations_Country] CHECK CONSTRAINT [FK_Country_inherits_Location]
GO
Boundary
CREATE TABLE [dbo].[Boundaries](
[LocationId] [int] NOT NULL,
[CentrePoint] [varbinary](max) NOT NULL,
[OriginalBoundary] [varbinary](max) NULL,
[LargeReducedBoundary] [varbinary](max) NULL,
[MediumReducedBoundary] [varbinary](max) NULL,
[SmallReducedBoundary] [varbinary](max) NULL,
CONSTRAINT [PK_Boundaries] PRIMARY KEY CLUSTERED
(
[LocationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Boundaries] WITH CHECK ADD CONSTRAINT [FK_LocationBoundary] FOREIGN KEY([LocationId])
REFERENCES [dbo].[Locations] ([LocationId])
GO
ALTER TABLE [dbo].[Boundaries] CHECK CONSTRAINT [FK_LocationBoundary]
GO
I don't see a need for SCOPE_IDENTITY or cursors if you approach the data in order of the parent/child relationship:
INSERT INTO LOCATION
SELECT t.name,
t.originallocationid
FROM ORIGINAL_TABLE t
GROUP BY t.name, t.originallocationid
INSERT INTO COUNTRY
SELECT DISTINCT
t.isocode,
l.locationid
FROM ORIGINAL_TABLE t
JOIN LOCATION l ON l.name = t.name
AND l.originallocationid = t.originalocationid
INSERT INTO BOUNDARY
SELECT DISTINCT
l.locationid,
t.centrepoint,
t.originalboundary,
t.largereducedboundary,
t.mediumreducedboundary,
t.smallreducedboundary
FROM ORIGINAL_TABLE t
JOIN LOCATION l ON l.name = t.name
AND l.originallocationid = t.originalocationid
After loading your Location table you could create a query that joins Location with your source single table. The join criteria would be the natural key (is that the Name column?) and it would return the new LocationId along with the Boundary data. The results would inserted into the new Boundary table.
I have several tables:
CREATE TABLE [dbo].[Tracks](
[Id] [uniqueidentifier] NOT NULL,
[Artist_Id] [uniqueidentifier] NOT NULL,
[Album_Id] [uniqueidentifier] NOT NULL,
[Title] [nvarchar](255) NOT NULL,
[Length] [int] NOT NULL,
CONSTRAINT [PK_Tracks_1] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[TrackHistory](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Track_Id] [uniqueidentifier] NOT NULL,
[Datetime] [datetime] NOT NULL,
CONSTRAINT [PK_TrackHistory] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [cooltunes].[dbo].[TrackHistory]
([Track_Id]
,[Datetime])
VALUES
("335294B0-735E-4E2C-8389-8326B17CE813"
,GETDATE())
CREATE TABLE [dbo].[Ratings](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Track_Id] [uniqueidentifier] NOT NULL,
[User_Id] [uniqueidentifier] NOT NULL,
[Rating] [tinyint] NOT NULL,
CONSTRAINT [PK_Ratings] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO [cooltunes].[dbo].[Ratings]
([Track_Id]
,[User_Id]
,[Rating])
VALUES
("335294B0-735E-4E2C-8389-8326B17CE813"
,"C7D62450-8BE6-40F6-80F1-A539DA301772"
,1)
Users
User_Id|Guid
Other fields
Links between the tables are pretty obvious.
TrackHistory has each track added to it as a row whenever it is played ie. a track will appear in there many times.
Ratings value will either be 1 or -1.
What I'm trying to do is select the Track with the highest rating, that is more than 2 hours old, and if there is a duplicate rating for a track (ie a track receives 6 +1 ratings and 1 - rating, giving that track a total rating of 5, another track also has a total rating of 5), the track that was last played the longest ago should be returned. (If all tracks have been played within the last 2 hours, no rows should be returned)
I'm getting somewhere doing each part individually using the link above, SUM(Value) and GROUP BY Track_Id, but I'm having trouble putting it all together.
Hopefully someone with a bit more (MS)SQL knowledge will be able to help me. Many thanks!
select top 1 t.Id, SUM(r.Rating) as Rating, MAX(Datetime) as LastPlayed
from Tracks t
inner join TrackHistory h on t.Id = h.Track_Id
inner join Ratings r on t.Id = r.Track_Id
where h.Track_Id not in (
select Track_Id
from TrackHistory
where Datetime > DATEADD(HOUR, -2, getdate())
)
group by t.Id
order by Rating desc, LastPlayed