Order By case when then with multiple ASC/DESC [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Hope this question has not been ask already.
My problem is :
Do you know how to do something like that
ORDER BY
CASE
WHEN job = "jounalist" then 1, date desc
WHEN job = "teacher" then 2, class asc
WHEN job = "dev" then 3, code asc
ELSE 4

You need separate case expressions. I'm not sure what 1, 2, and 3 represent. Let me assume they are meant to put the results in the order of the CASE expressions:
ORDER BY (CASE WHEN job = 'journalist' THEN 1
WHEN job = 'teacher' THEN 2
WHEN job = 'dev' THEN 3
ELSE 4
END),
(CASE WHEN job = 'journalist' THEN date END) DESC,
(CASE WHEN job = 'teacher' THEN class END),
(CASE WHEN job = 'code' THEN code END)
A CASE expression returns a single type. For this purpose, I don't recommend converting values to a single type. Instead, just use separate keys in the ORDER BY for the different groups.
I should also point out that some databases might have special functionality that would simplify some of this code.

ORDER BY
CASE
WHEN job = "jounalist" then 1
WHEN job = "teacher" then 2
WHEN job = "dev" then 3
ELSE 4
END asc
CASE
WHEN job = "jounalist" then Right(cast(1000000000 + Datediff(second, date, GetDate()) as nvarchar(100)), 9)
WHEN job = "teacher" then class
WHEN job = "dev" then code
ELSE N''
END asc
You can only return a single column of one data type from a case expression. I assume that class and code are nvarchar columns, and hence convert the time difference from date to now to an nvarchar(100). Also, assuming the value of column date is before the current date/time, and less than 1000000000 seconds so, the expression on it delives a 0-padded string which nicely sorts ascending the same way that sorting backwards on the date would sort.

Related

Updating Data into empty rows from different tables and summarizing the quantities using dates [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
Following is the query updating data into a table of empty rows from other connected columns and then summarising the quantities of each with respect to dates.
Update Dis
set Dis.OpStk = Sum(Case when ST.TrDate < FDate then ST.Qty end),--Quantity of stock before FDate
Dis.ClsStk = Sum(case when ST.TrDate >TDate then ST.Qty end ),--Quantity of stock After TDate
Dis.B14 = Sum(Case when Dis.FDate=DateADD(day,-14,FDate) then SL.Qty end),--Before 14 days
Dis.A14 = Sum(Case when Dis.TDate=DATEADD(day,14,TDate) then SL.Qty end),--After 14 days
Dis.A28 = Sum(Case when Dis.TDate=DATEADD(day,28,TDate) then SL.Qty end),--After 28 days
Dis.A60 = Sum(Case when Dis.TDate=DATEADD(day,60,TDate) then SL.Qty end),--60
Dis.A180 = Sum(Case when Dis.TDate=DATEADD(day,180,TDate) then SL.Qty end) --180
from #DisData Dis
Inner Join StockLine ST on Dis.ItemCode=ST.ItemCode
Inner Join SaleLine SL on Dis.ItemCode=SL.ItemCode
from these linked tables
My question is this query correct. If no then what is the correct form.
This is too long for a comment.
The query is not correct. It is not correct in any database, because of the SUM() in the SET clause. That is not allowed in SQL Server. It is not allowed by SQL in general.
Your question is unclear on what you intend to accomplish. You might be surprised, but a non-working query often does not contain such information.
I suspect that you want something like this:
Update Dis
set OpStk = st.opstk,
. . .
B14 = sl.b14,
. . .
from #DisData Dis cross apply
(select Sum(Case when ST.TrDate < dis.FDate then ST.Qty end) as OpStk,
. . . -- additional expressions here
from StockLine ST
where Dis.ItemCode = ST.ItemCode
) st cross apply
(select Sum(Case when Dis.FDate = DateADD(day, -14, dis.FDate) then SL.Qty end) as b14,
. . . -- additional expressions here
from SaleLine SL
where Dis.ItemCode = SL.ItemCode
) sl;
I do note that YOUR date arithmetic uses =, but the comments use words like "before" and "after". So, this will probably succeed in updating the table, but may not do what you really want.

On Oracle Discoverer, sum a group of accounts to be added in only one account [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am new here, and new in SQL
I am trying to reach something through discoverer report, I want to sum all P&L transactions related to previous years and adding it to the retained earning account without any need to make a retained earning entry
I tried using this
CASE WHEN ( Main Acnt Code = 2220000 AND Td Dept Code = 'ACT' )
THEN SUM(Td Doc Amt)+sum(CASE WHEN ( Main Acnt Code >= 3100000 AND Main Acnt Code <= 4999999 )
THEN SUM(Balance-YTD VAL)
ELSE 0 END
ELSE CASE WHEN Main Acnt Code >= 3100000
THEN 0 ELSE Balance-YTD VAL END END
Note:
2220000 = "Retained earning account"
3100000 to 4999999 = P&L account
'SUM(Balance-YTD VAL)': Balance and YTD VAL are 2 newly created columns To calculate the "opening balance"
'Balance'= the sum of all transactions since the beginning
'YTD VAL'= The sum of 2020 transactions only
The problem that it gives me a message similar to "Error in Formula - Nested aggregated functions are not allowed"
Your nested aggregated function are quickly found if you format your formula a bit
CASE WHEN ( Main Acnt Code = 2220000 AND Td Dept Code = 'ACT' )
THEN SUM(Td Doc Amt)+ sum(CASE WHEN ( Main Acnt Code >= 3100000 AND Main Acnt Code <= 4999999 )
! THEN SUM(Balance-YTD VAL) ELSE 0 END
! !
despite of missing closing bracklet and column names containing spaces..
Here are examples of valid usage of aggregated function, that should inspire you to get the result that you vaguely described:
select
sum(CASE WHEN ( Main_Acnt_Code >= 3100000 AND Main_Acnt_Code <= 4999999 )
THEN (Balance-YTD_VAL) ELSE 0 END) P_n_L,
sum(CASE WHEN ( Main_Acnt_Code = 2220000 AND Td_Dept_Code = 'ACT' )
THEN Td_Doc_Amt ELSE 0 END) as Retained_earning_account
from tab;
Adjust the WHEN predicates as required and finally add the two parts...

Apply multiple filters one at a time in query [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to apply filter in SQL query but in any order. What i mean is that if i have three parameters name para1, para2 and para3 and i want to apply only para1 and para3 parameters but do not want to apply para2 parameter in query or I want to apply only para3 parameter but don't want to apply para1 and para2 parameters in query.
In attached image if i want to apply filer on assigned_user_id and do not want to apply filer on Status or Dept column than result should show record filter on first parameter only.
Please help.
I think what you want is to have a stored proc where you pass 3 params p1,p2,p3, and one or more of them might be null. I will leave how to pass null for an unused parameter from whatever your caller application is up to you.
The way to do the sql selection, is this.
where
(#p1 is null null or column1=#p1)
and (#p2 is null or column2=#p2)
and (#p3 is null or column3=#p3)
Let ruby language for example. If you have any expressions to filter, you can manipulate with its as a strings:
conditions = {
para2: '> 0',
para3: '= 0',
para4: '!= 100500',
}
so, you can collect them to where clause:
where_clause_rules = conditions.map do |key, value|
"#{key} #{conditions[key]}"
end
where_clause = "WHERE #{where_clause_rules.join(' AND ')}"
and you have a result:
WHERE para2 > 0 AND para3 = 0 AND para4 != 100500
add this string to your sql:
SELECT *
FROM your_table
#{where_clause}
you give result:
SELECT *
FROM your_table
WHERE para2 > 0 AND para3 = 0 AND para4 != 100500
run sql:
Activerecord::Base.connection.execute(sql)
enjoy

Parenthesis around AND OR [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I needed some help in making sure I am using my parenthesis correctly around AND OR statements in SQL SERVER.
SELECT DISTINCT *
FROM Table
WHERE yearmonth = 201404
AND (HasA = 1 OR HasB = 1 OR hasC = 1)
AND (HasAX = 10 OR HasBX = 10 OR HasCX = 10)
When I have my parenthesis like above my second AND line of code, it also pulls out other values like example HasCX= 23.
Ironically this line of code works well:
AND (HasA = 1 OR HasB = 1 OR hasC = 1)
How should I write my parenthesis around this ?
AND (HasAX = 10 OR HasBX = 10 OR HasCX = 10)
It should only pull out data for where the condition is met with 10.
First, for your query, a cleaner way to write the logic is to use in:
SELECT DISTINCT *
FROM Table
WHERE yearmonth = 201404 AND
1 IN (HasA, HasB, HasC) AND
10 IN (HasAX, HasBX, HaxCX)
I suspect that what you really want is:
WHERE yearmonth = 201404 AND
((HasA = 1 AND HasAZ = 10) OR
(HasB = 1 AND HasBZ = 10) OR
(HasC = 1 AND HasCZ = 10)
)
Alternatively, you might want all of these connected by AND and not OR.
I think your query is right. Check your data. A row can have HasCx=23 but also have HasBX=1.

SQL Server Update via Select Statement

I have the following sql statement and I want to update a field on the rows returned from the select statement. Is this possible with my select? The things I have tried are not giving me the desired results:
SELECT
Flows_Flows.FlowID,
Flows_Flows.Active,
Flows_Flows.BeatID,
Flows_Flows.FlowTitle,
Flows_Flows.FlowFileName,
Flows_Flows.FlowFilePath,
Flows_Users.UserName,
Flows_Users.DisplayName,
Flows_Users.ImageName,
Flows_Flows.Created,
SUM(CASE WHEN [Like] = 1 THEN 1 ELSE 0 END) AS Likes,
SUM(CASE WHEN [Dislike] = 1 THEN 1 ELSE 0 END) AS Dislikes
FROM Flows_Flows
INNER JOIN Flows_Users ON Flows_Users.UserID = Flows_Flows.UserID
LEFT JOIN Flows_Flows_Likes_Dislikes ON
Flows_Flows.FlowID=Flows_Flows_Likes_Dislikes.FlowID
WHERE Flows_Flows.Active = '1' AND Flows_Flows.Created < DATEADD(day, -60, GETDATE())
Group By Flows_Flows.FlowID, Flows_Flows.Active, Flows_Flows.BeatID,
Flows_Flows.FlowTitle, Flows_Flows.FlowFileName, Flows_Flows.FlowFilePath,
Flows_Users.UserName, Flows_Users.DisplayName, Flows_Users.ImageName,
Flows_Flows.Created
Having SUM(CASE WHEN [Like] = 1 THEN 1 ELSE 0 END) = '0' AND SUM(CASE WHEN [Dislike] = 1
THEN 1 ELSE 0 END) >= '0'
This select statement returns exactly what I need but I want to change the Active field from 1 to 0.
yes - the general structure might be like this: (note you don't declare your primary key)
UPDATE mytable
set myCol = 1
where myPrimaryKey in (
select myPrimaryKey from mytable where interesting bits happen here )
Because you haven't made your question more clear in what result you want to achieve, I'll provide an answer with my own assumptions.
Assumption
You have a select statement that gives you stuffs, and it works as desired. What you want it to do is to make it return results and update those selected rows on the fly - basically like saying "find X, tell me about X and make it Y".
Anwser
If my assumption is correct, unfortunately I don't think there is any way you can do that. A select does not alter the table, it can only fetch information. Similarly, an update does not provide more detail than the number of rows updated.
But don't give up yet, depending on the result you want to achieve, you have alternatives.
Alternatives
If you just want to update the rows that you have selected, you can
simply write an UPDATE statement to do that, and #Randy has provided
a good example of how it will be written.
If you want to reduce calls to server, meaning you want to make just
one call to the server and get result, as well as to update the
rows, you can write store procedures to do that.
Store procedures are like functions you wrote in programming languages. It essentially defines a set of sql operations and gives them a name. Each time you call that store procedure, the set of operations gets executed with supplied inputs, if any.
So if you want to learn more about store procedures you can take a look at:
http://www.mysqltutorial.org/introduction-to-sql-stored-procedures.aspx
If I understand correctly you are looking for a syntax to be able to select the value of Active to be 0 if it is 1. The syntax for something like that is
SELECT
Active= CASE WHEN Active=1 THEN 0 ELSE Active END
FROM
<Tables>
WHERE
<JOIN Conditions>