Articles in this section
Category / Section

ORDER BY in Subquery Restricted - SQL Server

Published:

When utilizing Bold BI’s code view mode for SQL Server data source or data sources that use SQL Server as the data store database, users may encounter a limitation regarding the use of the “ORDER BY” clause in SQL Server code view mode.

orderby_restriction.png

ORDER BY in Subquery is restricted in SQL server

Using ORDER BY in subquery is restricted in the SQL server. Please find the below screenshot and article for your reference, https://learn.microsoft.com/en-us/answers/questions/1061604/the-order-by-clause-is-invalid-in-views-inline-fun

MicrosoftTeams-image_30.png

Bold BI also restricts the usage of ORDER BY in SQL Server code view mode for the same reason as we will be framing this “code view” query as a sub-query when bound to a widget.

Solution

  • You can use the TOP keyword after the SELECT or use the OFFSET keyword after the ORDER BY.

Using Top with limited rows:

    WITH RatingList AS (
        SELECT Top 100000 TrackId,EpisodeId,[Percent],Created,ROW_NUMBER() OVER (PARTITION BY TrackId, episodeid, videoid ORDER BY [percent] DESC) AS RowNum
        FROM VideoWatchedPercentStats
    )
    SELECT ChildJourneys.BusinessEntityId, ChildJourneys.Topic AS CompiledJourneyName, SubscriberJourneyTrace.SubscriberId AS EngageRecipientId,
    SubscriberJourneyTrace.EntryMethod,SubscriberJourneyTrace.ChildJourneyId, Entities.Topic AS EntityName,
    Entities.Parent AS BusinessEntityParentId, 'Video Watched' AS EventType,
    RR.Created AS EventDate, [Percent], 0 AS VideoLengthSeconds, 0 AS VideoTimeWatchedSeconds,
    EpisodeId, JourneyEpisodeTemplate_Videos.[Name] AS EpisodeName,SubscriberJourneyTrace.[Language]
    FROM RatingList RR
    LEFT JOIN  JourneyEpisodeTemplate_Videos ON RR.EpisodeId = JourneyEpisodeTemplate_Videos.Id
    INNER JOIN  SubscriberJourneyTrace ON RR.TrackId = SubscriberJourneyTrace.Id
    INNER JOIN ChildJourneys ON SubscriberJourneyTrace.ChildJourneyId = Journeys.Id
    INNER JOIN dbo.Entities ON Journeys.BusinessEntityId = Entities.Id
    WHERE RowNum = 1;

Using OFFSET with limited rows

    WITH RatingList AS (
        SELECT TrackId,EpisodeId,[Percent],Created,ROW_NUMBER() OVER (PARTITION BY TrackId, episodeid, videoid ORDER BY [percent] DESC) AS RowNum OFFSET 100000 ROWS
        FROM VideoWatchedPercentStats
    )
    SELECT Journeys.BusinessEntityId, Journeys.Topic AS CompiledJourneyName, SubscriberJourneyTrace.SubscriberId AS EngageRecipientId,
    SubscriberJourneyTrace.EntryMethod,SubscriberJourneyTrace.ChildJourneyId, Entities.Topic AS BusinessEntityName,
    Entities.Parent AS BusinessEntityParentId, 'Video Watched' AS EventType,
    RR.Created AS EventDate, [Percent], 0 AS VideoLengthSeconds, 0 AS VideoTimeWatchedSeconds,
    EpisodeId, JourneyEpisodeTemplate_Videos.[Name] AS EpisodeName,SubscriberJourneyTrace.[Language]
    FROM RatingList RR
    LEFT JOIN  JourneyEpisodeTemplate_Videos ON RR.EpisodeId = JourneyEpisodeTemplate_Videos.Id
    INNER JOIN  SubscriberJourneyTrace ON RR.TrackId = SubscriberJourneyTrace.Id
    INNER JOIN Journeys ON SubscriberJourneyTrace.ChildJourneyId = Journeys.Id
    INNER JOIN dbo.Entities ON Journeys.BusinessEntityId = Entities.Id
    WHERE RowNum = 1;

If you would rather not specify a number directly in the TOP query and want the entire data, you can use another subquery in-place that will give the total count in your table. Refer below examples

Using Top without Limited Rows:

    WITH RatingList AS (
        SELECT Top(SELECT (COUNT(*)) FROM RatingList RR) TrackId,EpisodeId,[Percent],Created,ROW_NUMBER() OVER (PARTITION BY TrackId, episodeid, videoid ORDER BY [percent] DESC) AS RowNum
        FROM VideoWatchedPercentStats
    )
    SELECT Journeys.BusinessEntityId, Journeys.Topic AS CompiledJourneyName, SubscriberJourneyTrace.SubscriberId AS EngageRecipientId,
    SubscriberJourneyTrace.EntryMethod,SubscriberJourneyTrace.ChildJourneyId, Entities.Topic AS BusinessEntityName,
    Entities.Parent AS BusinessEntityParentId, 'Video Watched' AS EventType,
    RR.Created AS EventDate, [Percent], 0 AS VideoLengthSeconds, 0 AS VideoTimeWatchedSeconds,
    EpisodeId, JourneyEpisodeTemplate_Videos.[Name] AS EpisodeName,SubscriberJourneyTrace.[Language]
    FROM RatingList RR
    LEFT JOIN  JourneyEpisodeTemplate_Videos ON RR.EpisodeId = JourneyEpisodeTemplate_Videos.Id
    INNER JOIN  SubscriberJourneyTrace ON RR.TrackId = SubscriberJourneyTrace.Id
    INNER JOIN Journeys ON SubscriberJourneyTrace.ChildJourneyId = Journeys.Id
    INNER JOIN dbo.Entities ON Journeys.BusinessEntityId = Entities.Id
    WHERE RowNum = 1;

Using OFFSET without Limited Rows:

    WITH RatingList AS (
        SELECT TrackId,EpisodeId,[Percent],Created,ROW_NUMBER() OVER (PARTITION BY TrackId, episodeid, videoid ORDER BY [percent] DESC) AS RowNum OFFSET (SELECT (COUNT(*)) FROM RatingList RR) ROWS
        FROM VideoWatchedPercentStats
    )
    SELECT Journeys.BusinessEntityId, Journeys.Topic AS CompiledJourneyName, SubscriberJourneyTrace.SubscriberId AS EngageRecipientId,
    SubscriberJourneyTrace.EntryMethod,SubscriberJourneyTrace.ChildJourneyId, Entities.Topic AS BusinessEntityName,
    Entities.Parent AS BusinessEntityParentId, 'Video Watched' AS EventType,
    RR.Created AS EventDate, [Percent], 0 AS VideoLengthSeconds, 0 AS VideoTimeWatchedSeconds,
    EpisodeId, EpisodeTemplate.[Name] AS EpisodeName,SubscriberJourneyTrace.[Language]
    FROM RatingList RR
    LEFT JOIN  EpisodeTemplate ON RR.EpisodeId = EpisodeTemplate.Id
    INNER JOIN  SubscriberJourneyTrace ON RR.TrackId = SubscriberJourneyTrace.Id
    INNER JOIN Journeys ON SubscriberJourneyTrace.ChildJourneyId = Journeys.Id
    INNER JOIN dbo.Entities ON Journeys.BusinessEntityId = Entities.Id
    WHERE RowNum = 1;
Was this article useful?
Like
Dislike
Help us improve this page
Please provide feedback or comments
SM
Written by Siranjeevi Murugan
Updated
Comments (0)
Please  to leave a comment
Access denied
Access denied