I would like to have a condition statement before Order By.
In my below query there is chance for Marks to be null, in that case I would like to Order by Rank Asc
SELECT TOP 1 P.[Score]
FROM dbo.[Profile] P
WHERE P.[ProfileId] = #ProfileId
ORDER BY P.[Marks] DESC AS [ProfileScore]
I tried changing it to the below way but it’s giving a compile error
SELECT TOP 1 P.[Score]
FROM dbo.[Profile] P
WHERE P.[ProfileId] = #ProfileId
ORDER BY
(CASE WHEN P.[Marks] IS NOT NULL THEN P.[Marks] END) DESC,
(CASE WHEN P.[Marks] IS NULL THEN P.[Rank] END) ASC AS [ProfileScore]
But it gives an error:
Incorrect syntax near the keyword 'DESC'
There is an AS [ProfileScore] too many in your ORDER BY. You cannot create aliases in ORDER BY.
If both Marks and Rank are numeric, I suggest:
SELECT TOP 1 P.[Score]
FROM dbo.[Profile] P
WHERE P.[ProfileId] = #ProfileId
ORDER BY CASE WHEN P.[Marks] IS NULL THEN P.[Rank] ELSE -P.[Marks] END;
Related
In my t-sql code below, in the INNER SELECT I am doing a SUM(t.WrittenPremium) and the t.WrittenPremium is defined as a MONEY datatype but then in the OUTER SELECT statement when I hover over the a.WrittenPremium it is NOW an INT datatype. The reason for the question is that I'm getting an error in a SSRS report that I'm working on from the results of this query stating that the WrittenPremium cannot be converted to String though I'm not trying to convert anything to a string. Any help/direction would be appreciated. Thanks.
Here is my SQL code:
SELECT
CASE
WHEN a.[Period] = '' THEN a.[Year] + ' - Total '+a.TermType
ELSE a.[Year]
END as [Year]
, a.[Period]
, a.TermType
, a.WrittenPremium
FROM (
SELECT
CASE
WHEN GROUPING (t.[Year]) = 1 THEN 'Total'
ELSE t.[Year]
END as [Year]
, ISNULL(t.[Period],'') as [Period]
, ISNULL(t.TermType,'') as TermType
, SUM(t.WrittenPremium) as WrittenPremium
, RN
FROM #temp t
GROUP BY GROUPING SETS ((t.[Year], t.[Period], t.TermType, t.RN), (t.[Year], t.TermType))
) a
ORDER BY 1 asc, a.RN asc, a.TermType;
Under the assuption that Year is an INT datatype I think the type mismatch is happen in the CASE setting Year. Please try this:
CASE
WHEN GROUPING (t.[Year]) = 1 THEN 'Total'
ELSE CAST(t.[Year] AS VARCHAR(10))
END as [Year]
I have data like in the below format
I want output in the below format
Please help me with the SQL code. Thanks !
Like I mention in the comments, you need to fix whatever it is that's inserting the data and not lose the values so that they become NULL in "newer" rows.
To get the results you want, you'll going to have to use row numbering and conditional aggregation, which is going to get messy the more columns you have; and why you need to fix the real problem. This will look something like this:
WITH CTE AS(
SELECT GroupingColumn,
NullableCol1,
NullableCol2,
DateColumn,
CASE WHEN NullableCol1 IS NOT NULL THEN ROW_NUMBER() OVER (PARTITION BY GroupingColumn, CASE WHEN NullableCol1 IS NULL THEN 1 ELSE 0 END ORDER BY DateColumn DESC) AS NullableCol1RN,
CASE WHEN NullableCol2 IS NOT NULL THEN ROW_NUMBER() OVER (PARTITION BY GroupingColumn, CASE WHEN NullableCol2 IS NULL THEN 1 ELSE 0 END ORDER BY DateColumn DESC) AS NullableCol2RN
FROM dbo.YourTable)
SELECT GroupingColumn,
MAX(CASE NullableCol1RN WHEN 1 THEN NullableCol1 END) AS NullableCol1,
MAX(CASE NullableCol2RN WHEN 1 THEN NullableCol2 END) AS NullableCol2,
MAX(DateColumn) AS DateColumn
FROM CTE;
I got a question and you can most likely help me.
I have got a query with a subquery that narrows the search. The query ends with this.
SELECT
*
FROM
Purchase
WHERE
Total < 5000
AND
Total >
(
SELECT TOP 1
buyamount
FROM
employee
WHERE
manager = 'TST'
ORDER BY
buyamount ASC
)
ORDER BY Date DESC
I want the value of the subquery after the ">"... but if the subquery gives nothing in return, i want it to be 0. How do i do this?
In the example you posted you could simply wrap the subquery in COALESCE and get your desired result.
SELECT
*
FROM
#Purchase
WHERE
Total < 5000
AND
Total > COALESCE(
(
SELECT TOP 1
buyamount
FROM
#employee
WHERE
manager = 'TST'
ORDER BY
buyamount ASC
), 0)
ORDER BY Date DESC
You could also use a variable in your provided example instead of a subquery. I prefer this approach because it separates the logic, making it easier to read. Subqueries can also be a performance killer. Having it broken out like this, it should perform better.
DECLARE #BuyAmount INT
SET #BuyAmount = (SELECT TOP 1 BuyAmount FROM #Employee WHERE Manager = 'TST' ORDER BY BuyAmount ASC)
IF #BuyAmount IS NULL SET #BuyAmount = 0
SELECT *
FROM #Purchase
WHERE Total < 5000 AND Total > #BuyAmount
ORDER BY Date DESC
I have a date column which has some NULL. I want to order by the date column ASC, but I need the NULL s to be at the bottom. How to do it on TSQL?
In standard SQL you can specify where to put nulls:
order by col asc nulls first
order by col asc nulls last
order by col desc nulls first
order by col desc nulls last
but T-SQL doesn't comply with the standard here. The order of NULLs depends on whether you sort ascending or descending in T-SQL:
order by col asc -- implies nulls first
order by col desc -- implies nulls last
With integers you could simply sort by the negatives:
order by -col asc -- sorts by +col desc, implies nulls first
order by -col desc -- sorts by +col asc, implies nulls last
But this is not possible with dates (or strings for that matter), so you must first sort by is null / is not null and only then by your column:
order by case when col is null then 1 else 2 end, col asc|desc -- i.e. nulls first
order by case when col is null then 2 else 1 end, col asc|desc -- i.e. nulls last
Select *
From YourTable
Order By case when DateCol is null then 0 else 1 end
,DateCol
Or even Order By IsNull(DateCol,'2525-12-31')
order by case when col_name is null then 1 else 2 end, col_name asc did the trick on Oracle. However the same on MS SQL Server pushes the NULL records down leaving non null to be on top of the result set.
This did the trick for me just now. Fortunately, I'm working with text. For anything numeric, I'd probably go with all 9's.
COALESCE(c.ScrubbedPath,'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'),
Sometimes, you may need to use a subquery to get this right:
select site_id, site_desc
from (
select null as site_id, 'null' as site_desc
union
select s.site_id,
s.site_code+'--'+s.site_description as site_desc
from site_master s with(nolock)
)x
order by (case when site_id is null then 0 else 1 end), site_desc
SELECT
MyColumn = 'something'
FROM table
WHERE MyColumn == 'something'
Possible to use MyColumn in WHERE clause?
EDIT:
Here's full query:
select TOP 10
PremiumYTDCurrent=Sum(CASE WHEN
AASI.Inv_Acctcur>='201101'
and AASI.Inv_Acctcur<='201102'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END),
PremiumYTDPrevious=Sum(CASE WHEN
AASI.Inv_Acctcur>='201001'
and AASI.Inv_Acctcur<='201002'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END),
R.STAFF, L.Description, L.LINE_OF_BUSINESS
from AAS_Invoice AASI,Invoice I,Revenue_Tracking R, Policy P, Line_Of_Business L
where I.Invoice_No=convert(Char,Convert(int,AASI.Inv_Entry_Num))
and I.Invoice=R.Invoice
and I.POLICY=P.POLICY
and L.LINE_OF_BUSINESS=P.LINE_OF_BUSINESS
and R.Organization IN (SELECT ST.ORGANIZATION FROM Staff ST WHERE ST.STAFF=14407)
and R.Staff=14407
and R.Activity_type='Broker'
and R.[Percent]>0
and PremiumYTDCurrent != 0
group by R.STAFF, L.Description, L.LINE_OF_BUSINESS
order by PremiumYTDCurrent DESC, PremiumYTDPrevious DESC, average_policy DESC
You can not use the column in the where clause. Use the expression instead.
and Sum(CASE WHEN
AASI.Inv_Acctcur>='201101'
and AASI.Inv_Acctcur<='201102'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END) <> 0
Edit 1
Did not notice the SUM clause.
Try add it as a HAVING clause instead after order by.
having Sum(CASE WHEN
AASI.Inv_Acctcur>='201101'
and AASI.Inv_Acctcur<='201102'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END) != 0
You could wrap the SQL up in a nested statement, a horrendously simple example being, e.g.:
SELECT MyMadeUpColumnName, col2, AnotherMadeUpColumn FROM (
SELECT SUM(sillycolumn) AS 'MyMadeUpColumnName', col2 FROM table GROUP BY col2
) AS t
WHERE t.AnotherMadeUpColumn <> 0
Any column names that you (re)define in the derived table become the actual column names for the parent select.