ORDER BY issue in Select distinct case - sql

SELECT DISTINCT
CAST(dpt.TrackId AS varchar(20)) + ' , ' + CONVERT(VARCHAR(19), dpt.CreatedDate) AS TrackId
FROM
ExcelUtilityTemplate
INNER JOIN
DataImportProcessTracker dpt ON ExcelUtilityTemplate.TemplateId = dpt.TemplateId
INNER JOIN
TA_JDSU..Employee_Temp et ON et.TrackId = dpt.TrackId
WHERE
(ExcelUtilityTemplate.ClientId = 'e0a94231-3265-4277-9cc3-236d9a2ead49'
AND et.RowStatus = 1)
ORDER BY
dpt.CreatedDate desc
My above query throws the following error:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
I want to sort my records on the basis of CreatedDate.
Hoping for quick reply. Thanks

Modify your query as follows:
SELECT distinct Cast(dpt.TrackId as varchar(20)) +' , '+ CONVERT(VARCHAR(19),dpt.CreatedDate) as TrackId ,dpt.CreatedDate
FROM ExcelUtilityTemplate INNER JOIN
DataImportProcessTracker dpt ON ExcelUtilityTemplate.TemplateId = dpt.TemplateId
inner join TA_JDSU..Employee_Temp et on et.TrackId=dpt.TrackId
WHERE (ExcelUtilityTemplate.ClientId = 'e0a94231-3265-4277-9cc3-236d9a2ead49' and et.RowStatus=1) order by dpt.CreatedDate desc
Explanation:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
When ever you are using distinct with select and ordering by some field. Then , That field should be included in your select clause
Hope this helps..

You'll need to order by the same value as you're doing DISTINCT on, since otherwise you may end up with more than one value to order by for each row;
SELECT distinct CAST(dpt.TrackId as varchar(20)) +' , '+
CONVERT(VARCHAR(19),dpt.CreatedDate) as TrackId
FROM ExcelUtilityTemplate
INNER JOIN DataImportProcessTracker dpt
ON ExcelUtilityTemplate.TemplateId = dpt.TemplateId
INNER JOIN TA_JDSU..Employee_Temp et
ON et.TrackId=dpt.TrackId
WHERE (ExcelUtilityTemplate.ClientId = 'e0a94231-3265-4277-9cc3-236d9a2ead49'
AND et.RowStatus=1)
ORDER BY CAST(dpt.TrackId as varchar(20)) +' , '+
CONVERT(VARCHAR(19),dpt.CreatedDate) DESC

Related

How to use keyset pagination?

Suppose I have total 800 eligible rows in database which is ordered by a column requisitionid in descending order. I want to display the records in 80 pages each page having 10 rows. We are using requisitionid as seek predicate. So the predicate should be less than or greater than? As the query will progress from UI (Angular + primeNG), I want to send just one parameter - requisitionid. If it is less than query, then the query will be SELECT ... FROM ... where requisitionid < ?, so here we are talking about first row. If we go for greater than query i.e. SELECT ... FROM ... where requisitionid > ?, here we are talking about last row of the page.
Please refer to Life without offset
EDIT
Actual code:
with topten as (SELECT DISTINCT TOP 10
REQN.CASE_ID
,userContact2.BV_First_Name + ' ' + userContact2.BV_Last_Name ReQCreater
,REQN.BV_Internal_Job_Title
,REQN.BV_Posted_Job_Title as postedJobTitle
,REQN.BV_Status
,REQN.BV_Taleo_Id
,REQN.BV_WD_PositionID
,jobcode.BV_Job_Code
,loc.BV_LocationCode
,loc.BV_LocationName
,D.BV_Division_Code AS 'divCode',
ISNULL(loc.BV_Address1,'') + CASE WHEN ISNULL(loc.BV_Address1,'') = '' THEN '' ELSE ', ' END + ISNULL(loc.BV_Address2,'') + CASE WHEN ISNULL(loc.BV_Address2,'') = '' THEN '' ELSE ', ' END
+ ISNULL(loc.BV_City,'') + CASE WHEN ISNULL(loc.BV_City,'') = '' THEN '' ELSE ', ' END + ISNULL(loc.BV_State,'') + CASE WHEN ISNULL(loc.BV_State,'') = '' THEN '' ELSE (case when ISNULL(loc.BV_ZipCode,'') = '' THEN '' ELSE ', ' END) END
+ ISNULL(loc.BV_ZipCode,'') AS locationAddress
from dbo.CW_V_REQN as REQN
INNER JOIN dbo.CW_TL_Requisition__Location_Master as reqLocLink on REQN.CASE_ID = reqLocLink.FROM_ID
INNER JOIN dbo.CW_V_LOCTMAST as loc on loc.CASE_ID = reqLocLink.TO_ID
INNER JOIN dbo.CW_TL_UserContactInfo__Location_Master as locUserLink on locUserLink.TO_ID = loc.CASE_ID
INNER JOIN dbo.CW_V_USERCONT as userContact on userContact.CASE_ID = locUserLink.FROM_ID
LEFT JOIN dbo.CW_TL_Requisition__Department as reqDeptLink on REQN.CASE_ID = reqDeptLink.FROM_ID
INNER JOIN dbo.CW_V_DEPARTME as dept on dept.CASE_ID = reqDeptLink.TO_ID
LEFT JOIN dbo.CW_TL_UserContactInfo__Department_Master as deptUserLink on dept.CASE_ID=deptUserLink.TO_ID
INNER JOIN dbo.CW_TL_Requisition__Job_Code as reqJobLink on REQN.CASE_ID = reqJobLink.FROM_ID
LEFT JOIN dbo.CW_V_JOBCODE as jobcode on jobcode.CASE_ID = reqJobLink.TO_ID
LEFT JOIN dbo.CW_V_USERCONT as userContact2 on (userContact2.BV_Login_Name = REQN.CREATED_BY)
LEFT JOIN CW_TL_LocationMaster__Division_Master LD ON (LD.FROM_ID = loc.CASE_ID)
LEFT JOIN CW_V_DIVISION D ON (D.CASE_ID = LD.TO_ID)
WHERE userContact.BV_Login_Name = #LOGINNAME
AND REQN.CASE_ID < #MINCASEIDPREVPAGE
ORDER BY REQN.CASE_ID DESC
)
select topten.*
, T.*
from topten
cross join (select min(case_id) as min from topten) as T
For key based pagination on a descending key, the WHERE clause predicate should be < for the next page and > for the previous page. Also, the ORDER BY clause for the previous page needs to be ASC (for the TOP predicate) along an outer DESC (for the descending key display sequence). Below is an example.
--create test table with sample data
CREATE TABLE dbo.YourTable(
requisitionid int PRIMARY KEY
);
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t1000 AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
INSERT INTO dbo.YourTable WITH(TABLOCKX)
SELECT num
FROM t1000
WHERE num <= 800;
GO
--query for first page (page 1) on descending key (returns 800-791)
SELECT TOP(10) requisitionid
FROM YourTable
ORDER BY requisitionid DESC;
GO
--query for next page (page 2) on descending key (returns 790-781)
DECLARE #LastRequisitionIdOnPage int = 791;
SELECT TOP(10) requisitionid
FROM YourTable
WHERE requisitionid < #LastRequisitionIdOnPage
ORDER BY requisitionid DESC;
GO
--query for previous page (page 1) on descending key (returns 800-791)
DECLARE #FirstRequisitionIdOnPage int = 790;
SELECT requisitionid
FROM (
SELECT TOP(10) requisitionid
FROM YourTable
WHERE requisitionid > #FirstRequisitionIdOnPage
ORDER BY requisitionid ASC
) AS prev_page
ORDER BY requisitionid DESC;;
GO
If I understand your question, you should be able to use the follow clause at the end of your SELECT query:
OFFSET (#Page * 10) ROWS FETCH NEXT 10 ROWS ONLY
If this is not what you are looking for, please post your current query so we can see what you are doing now.

How to get values other from a string in SQL

I'm using the stuff function to get a list of ids. But there are some values that are duplicate:
----------
3180,3181,3182,3180,4180
----------
3183,3184,3184,4181
I just want to get the list of ids that are not duplicated, desired results:
----------
3181,3182,4180
----------
3183,4181
This my query:
SELECT oa.AssetId,
oal.AssetLineId,
SNIds = STUFF((SELECT ', ' + CAST(isn1.Id AS VARCHAR(MAX))
FROM dbo.InventoryOperation o1
INNER JOIN dbo.InventoryOperationAsset oa1 ON oa1.OperationId = o1.OperationId
INNER JOIN dbo.InventoryOperationAssetLine oal1 ON oal1.OperationAssetId = oa1.OperationAssetId
INNER JOIN dbo.InventoryOperationAssetLineSerialNumber ioalsn1 ON ioalsn1.OperationAssetLineId = oal1.OperationAssetLineId
INNER JOIN dbo.InventorySerialNumber isn1 ON isn1.Id = ioalsn1.SerialId
WHERE oa.AssetId = oa1.AssetId AND oal.AssetLineId = oal1.AssetLineId
FOR XML PATH('')),1,2,'')
FROM dbo.InventoryOperation o
INNER JOIN dbo.InventoryOperationAsset oa ON oa.OperationId = o.OperationId
INNER JOIN dbo.InventoryOperationAssetLine oal ON oal.OperationAssetId = oa.OperationAssetId
INNER JOIN dbo.InventoryOperationAssetLineSerialNumber ioalsn ON ioalsn.OperationAssetLineId = oal.OperationAssetLineId
GROUP BY oa.AssetId, oal.AssetLineId;
Can anyone help me with this issue? Thanks in advance if anyone could help.
You could use
SELECT DISTINCT columns FROM table;
That makes sure you only get non duplicates.
Query that provides data to STUFF function should use following query to get only unique ids (e.g. 3181,3182,4180,3183,4181) and not the ones that have duplicates (e.g. 3180,3184)
SELECT column_name
FROM TABLE_NAME
GROUP BY column_name
HAVING COUNT(*) = 1;
Updating answer with STUFF function sample ...
SELECT STUFF(', ' + REPLACE((SELECT id + ', ' AS 'data()'
FROM stackoverflow
GROUP BY id
HAVING COUNT(*) = 1
FOR XML PATH('')), '', ''), 1, 2, '')
Sample Run

SQL Highest Value With Group

What I need to do is get the Highest StockOnSite per ProductID ( calculating the StockDifference ) record and concatenate StockOnSite with StockOffsite to create a column AllStock
I am completely lost? as I cannot group as we have a StockOnSite and StockOffsite
Here is the SQLFiddle
Fiddle
This is not a duplicate post, as the outer select complicates the grouping.
Thanks
I believe this is the query you've been looking for.
It evaluates StockDiff as you suggested: StockOnSite - StockOffSite and then takes the highest value for every SiteID
SELECT
SiteID, Description, StockOnSite, StockOffsite, AllStock, LastStockUpdateDateTime, StockDiff
FROM (
SELECT
*,
rank() OVER (PARTITION BY SiteID ORDER BY StockDiff DESC) AS rank
FROM (
SELECT
s.SiteID,
s.Description,
p.StockOnSite,
p.StockOffsite,
CAST(p.StockOnSite AS varchar(10)) + '/' + CAST(p.StockOffSite AS varchar(10)) AS AllStock,
p.LastStockUpdateDateTime,
p.StockOnSite - p.StockOffSite AS StockDiff
FROM
Sites s
JOIN Products p ON s.SiteID = p.OnSiteID
) foo
) goo
WHERE rank = 1
ORDER BY 1
I used a Window function to get it done.
Edit
If you need highest StockOnSite you can easily modify the Window Function by replacing StockDiff in ORDER BY StockDiff DESC with StockOnSite
You wanted to highest StockOnSite by ProductID, but the sample set all had unique productIDs. This query will get what you're asking for, but I think your question might be unclear as to what your result set needs to look like.
select pr.ProductID
, s.SiteID
,s.Description
,StockOnSite
,StockOffsite
,AllStock = cast(coalesce(pr.StockOnSite,'') as varchar(10)) + '-' + cast(coalesce(pr.StockOffsite,'') as varchar(10))
,LastStockUpdateDateTime = pr.LastStockUpdateDateTime
,Stockdiff = StockOnSite - StockOffsite
from Products pr
inner join (
select pr.ProductID
, MAX(StockOnSite) MaxStockOnSite
from dbo.Products pr
group by [ProductID]
) x
ON x.ProductID = pr.ProductID
and x.MaxStockOnSite = pr.StockOnSite
inner join dbo.Sites s
ON pr.OnSiteId = s.SiteId
this query may help you :
select * from Products p1
join
(
select onsiteid,max(stockonsite-stockoffsite) as stockdiff
from products
group by onsiteid
) p2
on p1.onsiteid = p2.onsiteid and (p1.stockonsite - p1.stockoffsite) = p2.stockdiff
you can modify select as per your need.

How to use CASE statement along with a Sub Query in SQL Server 2008

I have the following query.
SELECT *
FROM
(SELECT
Users.ccMailName as [User Name],
(CASE WHEN UserRoleAssigns.Team_ID > 0 THEN (select Team from Teams where team_ID = UserRoleAssigns.team_id) Else "All" END) as Team,
Users.User_WWID [WWID],
Users.Created_Date,
Role,
COUNT(Role) as HasRole
FROM
UserRoles
RIGHT OUTER JOIN
UserRoleAssigns ON UserRoles.Role_ID = UserRoleAssigns.Role_ID
RIGHT OUTER JOIN
Users ON UserRoleAssigns.User_WWID = Users.User_WWID
GROUP BY
Users.ccMailName, Users.Created_Date, Users.User_WWID, Role, UserRoleAssigns.Team_ID
) as Tbl1
PIVOT (
SUM(HasRole)
FOR [Role] IN (
' + #PivotColumnHeaders + '
)
) AS pt
ORDER BY Created_Date desc '
When I run it I am getting the following error:
Invalid column name 'All'.
The query works fine without the case statement with just the sub query alone. Essentially, first I want to check whether UserRoleAssigns.Team_ID > 0. If so, then get data from the subquery.
Otherwise default the value to "All".
Thanks
you can rewrite your sql like this:
SELECT *
FROM
(SELECT
Users.ccMailName as [User Name],
(CASE WHEN UserRoleAssigns.Team_ID > 0 THEN UserRoleAssigns.team_id Else 'All' END) as Team,
Users.User_WWID [WWID],
Users.Created_Date,
Role,
COUNT(Role) as HasRole
FROM
UserRoles
RIGHT OUTER JOIN
(select * from UserRoleAssigns u left join select Team from Teams t on u.team_ID=t.eam_ID) UserRoleAssigns
ON UserRoles.Role_ID = UserRoleAssigns.Role_ID
RIGHT OUTER JOIN
Users ON UserRoleAssigns.User_WWID = Users.User_WWID
GROUP BY
Users.ccMailName, Users.Created_Date, Users.User_WWID, Role, UserRoleAssigns.Team_ID
) as Tbl1
PIVOT (
SUM(HasRole)
FOR [Role] IN (
' + #PivotColumnHeaders + '
)
) AS pt
ORDER BY Created_Date desc '
if you are assigning the sql to a variable,which I think you are doing because of the construct of the pivot part, then you may need to escape the single quotes in 'All' by using two single quotes i.e ''All''

Only one expression can be specified in the select list

I need to get this sql query working:
SELECT TOP 15 id, thumb, width, height
FROM (SELECT vPictures.id, vPictures.thumb, vPictureCrops.width, vPictureCrops.height
FROM vPictures INNER JOIN
vPictureCrops ON vPictures.id = vPictureCrops.picid
WHERE (vPictureCrops.width = '602') AND (vPictureCrops.height = '131')
GROUP BY vPictures.id, vPictures.thumb, vPictureCrops.width, vPictureCrops.height) AS derivedtbl_1
WHERE (id NOT IN
(SELECT TOP 0 vPictures_1.id, vPictures_1.datetime, vPictures_1.url, vPictures_1.author, vPictures_1.companyID, vPictures_1.source,
vPictures_1.people, vPictures_1.text, vPictures_1.thumb, vPictures_1.logo, vPictureCrops_1.id AS Expr1, vPictureCrops_1.picid,
vPictureCrops_1.url AS Expr2, vPictureCrops_1.width, vPictureCrops_1.height
FROM vPictures AS vPictures_1 INNER JOIN
vPictureCrops AS vPictureCrops_1 ON vPictures_1.id = vPictureCrops_1.picid))
ORDER BY id DESC
Can you help me?
The error message:
"Only one expression can be specified in the select list when the subquery is not introduced with EXISTS)"
The Where (ID not IN(
The Select must only have one field are the IN can not understand which column you are trying to parse.
Eg from here
USE AdventureWorks2008R2;
GO
SELECT p.FirstName, p.LastName
FROM Person.Person AS p
JOIN Sales.SalesPerson AS sp
ON p.BusinessEntityID = sp.BusinessEntityID
WHERE p.BusinessEntityID IN
(SELECT BusinessEntityID
FROM Sales.SalesPerson
WHERE SalesQuota > 250000);
GO
Not sure what you are trying to achieve with the query anyway, can you explain the usage of the where in clause,
I can see two problems with (id NOT IN (SELECT TOP 0 vPictures_1.id, ...
only when column should be specified in the select statement after IN. For example (id NOT IN (SELECT vPictures_1.id FROM ...
even if you make it just one field vPictures_1.id the condition will always be false because of top 0.