i am using this sql block right now
SELECT mail_id,
CASE consignor
WHEN 'aby' THEN
'con'
ELSE
'rec'
END AS type,
CASE consignor
WHEN 'aby' THEN
recipient
ELSE
consignor
END AS other,
mail, mail_time
FROM mail m
WHERE m.consignor = user OR m.recipient = user
ORDER BY mail_time DESC
As you can see 2 case statements does exactly same job here so i thought i somehow can combine them. However my attemps did not yield any results. Anyone knows something better here?
What i've tried?
SELECT mail_id,
CASE consignor
WHEN 'aby' THEN
'con', recipient
ELSE
'rec', consignor
END AS ( type, other ),
mail, mail_time
FROM mail m
WHERE m.consignor = user OR m.recipient = user
ORDER BY mail_time DESC
Related
I want to separate the 1st transaction date of every client to another column. Im not good at explaining. Hope the image below is enough to clarify my question..
I want to generate a result like in the picture. **I just edited this picture for the reference of the result that I want.
this my sqlfiddle ---> http://sqlfiddle.com/#!9/bebf5/1
I believe PN_NO represents client. We would need to perform ordering of rows based on PN_NO and Pay Date columns. It is needed to identify first transaction date. Please try below query.
SELECT
SCHED_NO,
PN_NO,
PAY_PRIN,
PAY_DATE,
CASE WHEN PN_NO_Rank=1 THEN PAY_DATE ELSE '' END AS BEGIN,
CASE WHEN PN_NO_Rank <>1 THEN PAY_DATE ELSE '' END AS CR
FROM
(
SELECT
SCHED_NO,
PN_NO,
PAY_PRIN,
PAY_DATE,
#PN_NO_Rank := IF(#current_PN_NO = PN_NO, #PN_NO_Rank + 1, 1) AS PN_NO_Rank,
#current_PN_NO := PN_NO
FROM PAY_SCHED
ORDER BY PN_NO, PAY_DATE ASC
) AS Temp
That should help:
SELECT SCHED_NO, PN_NO, PAY_PRIN, PAY_DATE,
CASE WHEN pay_date = (select min(pay_date) from pay_sched where pn_no=ps.pn_no) THEN pay_date ELSE NULL END as "BEGIN",
CASE WHEN pay_date = (select min(pay_date) from pay_sched where pn_no=ps.pn_no) THEN NULL ELSE pay_date END as "CR"
FROM PAY_SCHED ps order by pn_no, pay_date
http://sqlfiddle.com/#!9/bebf5/26/0
Trying to convert below query into SQL, query works fine on MySQL. Problem seems to be the CASE WHEN area field I get same error.
show Msg 102, Level 15, State 1, Line 44 Incorrect syntax near '='.
Msg 156, Level 15, State 1, Line 47 Incorrect syntax near the keyword
'AND'. Msg 156, Level 15, State 1, Line 49 Incorrect syntax near the
keyword 'ELSE'.
WHEN T.[StatusID] = 3
THEN
CASE WHEN (((SELECT COUNT(TA1.[Approver_ID]) FROM [QESTORM].[dbo].[CR_TicketApproval] TA1
INNER JOIN [QESTORM].[dbo].[CR_ControlFlow_SubRoute] CFSR1 ON TA1.[SubRoute_ID] = CFSR1.[ID]
WHERE TA1.[Ticket_ID]= #iTkID AND TA1.Active=1 AND CFSR1.Active=1 AND CFSR1.[Sequence] =(SELECT CFSR2.[Sequence] FROM [QESTORM].[dbo].[CR_Ticket] T2 INNER JOIN [QESTORM].[dbo].[CR_ControlFlow_SubRoute] CFSR2 ON T2.[SubRouteID] = CFSR2.[ID]
WHERE T2.[ID] = #iTkID))<(SELECT COUNT(DISTINCT CFSR1.[ID])FROM [QESTORM].[dbo].[CR_Ticket] AS T1 INNER JOIN [QESTORM].[dbo].[CR_ControlFlow_Route] AS CFR1 ON T1.[FormID] = CFR1.[FormID] INNER JOIN [QESTORM].[dbo].[CR_ControlFlow_SubRoute] AS CFSR1 ON CFR1.[ID] = CFSR1.[RouteID]
WHERE CFR1.[Active] = 1 AND CFSR1.[Active] = 1 AND T1.[ID] = #iTkID AND CFSR1.[Category] = 1 AND CFSR1.[Sequence] = ( SELECT CFSR2.[Sequence] FROM [QESTORM].[dbo].[CR_Ticket] AS T2 INNER JOIN [QESTORM].[dbo].[CR_ControlFlow_SubRoute] AS CFSR2 ON T2.[SubRouteID] = CFSR2.[ID]
WHERE T2.[ID] = #iTkID))))
THEN
CASE WHEN ((SELECT COUNT(1) FROM [QESTORM].[dbo].[CR_TicketApproval] WHERE [Ticket_ID]=#iTkID And [Active]=1) = 0)
THEN
--ERROR SHOW HERE => ((T.[AuditUser_ID] = '444' OR T.[AuditUser_ID] IS NULL) AND (nx.actor = 2 OR appSameSeq.NTLogin=in_NTLogin)
AND nx.actor=3
AND srSameSeq.subRouteID NOT IN (SELECT subRouteID FROM [QESTORM].[dbo].[CR_TicketApproval] WHERE [Ticket_ID]=#iTkID AND Active=1 )
AND appSameSeq.NTLogin=in_NTLogin
AND nx.actor=3 AND srSameSeq.subRouteID NOT IN (SELECT subRouteID FROM [QESTORM].[dbo].[CR_TicketApproval] WHERE [Ticket_ID] = #iTkID AND Active = 1)
ELSE 0
END
I'll toss my hat in the ring.
There may be more than one thing wrong with that SQL statement. What I'll point out is this:
CASE WHEN ((SELECT COUNT(1) FROM [QESTORM].[dbo]. [CR_TicketApproval] WHERE [Ticket_ID]=#iTkID And [Active]=1) = 0)
THEN
--ERROR SHOW HERE => ((T.[AuditUser_ID] = '444' OR T.[AuditUser_ID] IS NULL) AND (nx.actor = 2 OR appSameSeq.NTLogin=in_NTLogin)
AND nx.actor=3
AND srSameSeq.subRouteID NOT IN (SELECT subRouteID FROM [QESTORM].[dbo].[CR_TicketApproval] WHERE [Ticket_ID]=#iTkID AND Active=1 )
AND appSameSeq.NTLogin=in_NTLogin
AND nx.actor=3 AND srSameSeq.subRouteID NOT IN (SELECT subRouteID FROM [QESTORM].[dbo].[CR_TicketApproval] WHERE [Ticket_ID] = #iTkID AND Active = 1)
ELSE 0
END
Are you trying to evaluate a conditional expression, and return the result as a 1 or 0, as if it were a Boolean expression in a programming language?
That doesn't work in TSQL. This kind of expression evaluation:
SET #value = (1 > 0)
... will produce an error. You can't evaluate a conditional expression: you can only use it in a test, like in a WHERE, HAVING, or WHEN clause.
So, if that's what you're doing, you might do better to wrap your conditional evaluation in yet another CASE statement, like this:
THEN
CASE WHEN {complex conditional statement}
THEN 1
ELSE 0
END
ELSE
0
END
One other thing: this is an extremely complex query statement! I haven't analyzed it enough to see whether it could be simplified, but I'd suggest that you do so, with an eye toward using Common Table Expressions in place of some of your subqueries. This can make the query a lot easier to understand (and debug).
We are missing the complete query but it looks like you are opening too many parentheses.
If you look at the line where your error is shown:
((T.[AuditUser_ID] = '444' OR T.[AuditUser_ID] IS NULL) AND (nx.actor = 2 OR appSameSeq.NTLogin=in_NTLogin)
You are opening 2 parentheses but only close one.
That is why you get the error near else because you need to close that second parentheses before you can have an else
So you would need either
((T.[AuditUser_ID] = '444' OR T.[AuditUser_ID] IS NULL) AND (nx.actor = 2 OR appSameSeq.NTLogin=in_NTLogin))
or
(T.[AuditUser_ID] = '444' OR T.[AuditUser_ID] IS NULL) AND (nx.actor = 2 OR appSameSeq.NTLogin=in_NTLogin)
on that line
It looks like you don't have a 'return value' for your case statement on that specific line.
When you flatten your CASE WHEN statement you have something like this:
CASE WHEN <something> THEN
CASE WHEN <something else> THEN
CASE WHEN <something else again> THEN
-- THEN WHAT ?
ELSE
0
END
END
END
Instead of putting a value on the --THEN WHAT spot, you put another conditional statement. You have to select a value here.
I'm migrating a project to Laravel 4 and I am stuck with a quite complex query, which I'd like to migrate into a proper Eloquent query.
I have a table that contains chat messages, called chat_messages with a representing Model Chatmessage
The table contains a sender and a receipient column with a user id linking to the users table and User Model.
The query to get a list with all user IDs of all chat partners in raw SQL on the old version of the application is as follows:
$sql_allChatPartners = "SELECT DISTINCT chatPartner
FROM ( SELECT * FROM (
SELECT cm_receipient AS chatPartner, cm_sent_at
FROM chat_messages WHERE cm_sender = '".$me->userID."'
UNION
SELECT cm_sender AS chatPartner, cm_sent_at
FROM chat_messages WHERE cm_receipient = '".$me->userID."'
) whateva ORDER BY whateva.cm_sent_at DESC ) other";
Sorry for naming the "fake" tables whateva and other :-)
Could anyone put me in the right direction to do this with Eloquent Querybuilder?
It is important that I get the list of chatPartner IDs in the correct order, where the last chat message has been exchanged as first chatPartner. And the chatPartner where longest inactivity was in the chat as last entry.
This is what I got so far in my User Model...
public function allopenchats(){
$asSender = Chatmessage::where('sender', $this->id)->select('receipient as chatPartner, created_at');
$asBoth = Chatmessage::where('receipient', $this->id)->select('sender as chatPartner, created_at')
->union($asSender)->orderBy('created_at', 'desc')->get();
}
I renamed the columns cm_receipient to receipient, cm_sender to sender and sent_at to created_at in the new database for the new version
Your help would be very much appreciated!
You sql may change to:
SELECT IF (cm_receipient = '10', cm_sender, IF (cm_sender = '10',cm_receipient, 'no')) AS chatPartner, cm_sent_at
FROM chat_messages
WHERE cm_receipient = '10' OR cm_sender = '10'
GROUP BY chatPartner
HAVING chatPartner != 'no'
order by cm_sent_at DESC
In orm:
Chatmessage::where('sender','=',$this->id)
->orWhere('receipient','=',$this->id)
->select(DB::raw('IF (receipient = '.$this->id.', sender, IF (sender = '.$this->id.',receipient, 'no' )) AS chatPartner'), 'created_at')
->groupBy('chatPartner')
->having('chatPartner', '!=', 'no')
->orderBy('created_at', 'desc')
->get();
Thanks very much to Vitalik_74, I wouldn't have come that far without him.
Here is now the final query, although its not in ORM, but it is working fine and gives me the result I need.
$result = DB::select("SELECT *
FROM (
SELECT IF( receipient = '".$this->id."', sender, IF( sender = '".$this->id."', receipient, 'no' ) ) AS chatPartner, created_at
FROM chatmessages
WHERE receipient = '".$this->id."'
OR sender = '".$this->id."'
HAVING chatPartner != 'no'
ORDER BY created_at DESC
)whateva
GROUP BY whateva.chatPartner
ORDER BY whateva.created_at DESC");
if there is someone out there who can do this query with the Laravel Query Builder, I would be happy to see it. For now I'll leave it like this.
I am using two tables here projections_report p and access_rights a. I can't find out why I am getting the error:
subquery returns more than one row
(case when paramChannel='AllC' then p.gl_sal_chan in
(case when dc_lob=0 then (select distinct pr.gl_sal_chan from
projections_report pr) else (select distinct pr1.gl_sal_chan
from projections_report pr1 where pr1.gl_sal_chan
in (select distinct a.gl_sal_chan from access_rights
a where a.userid= paramUserId)) end)
else p.gl_sal_chan = paramChannel end)
I tried using all and any keywords. Please help.
Thanks in advance.
USE LIMIT in sub queries to return only one record as you are using distinct, it might return more than one record
I tried to do it in another way and got it right. Firstly I changed the statement in else condition of second case statement to
(select distinct gl_sal_chan from access_rights where userid = paramUserid)
as both return the same result(my bad) and secondly I changed the entire condition to
(case when (paramChannel = 'AllC' && dc_lob = 0) then '%' = '%' else
(case when (paramChannel='AllC' && dc_lob != 0) then
gl_sal_chan in (select distinct gl_sal_chan from access_rights where userid = paramUserid)
else gl_sal_chan= paramChannel end)end)
Anyway Thanks #all :)
I have a table that, due to the third party system we are using, sometimes has duplicate data. Since the model uses an EAV method there's no way to filter this the "right" way, so I am aggregating the data into a View - I know this is a data collection problem but it's easier for me to fix it on the display end than go through this system and potentially break existing data and forms. I need to check one of two fields to see if one or both are entered, but only pick one (otherwise the name displays twice like this: "John,John" instead of just "John"). Here's my code for the relevant part:
group_concat(
(
case when (`s`.`fieldid` = 2) then `s`.`data`
else
case when (`s`.`fieldid` = 35) then `s`.`data`
else NULL end
end
) separator ','),_utf8'') as first_name
If both fieldid 2 and fieldid 35 are entered, I would expect this to just return the value from fieldid = 2 and not the value from fieldid = 35, since the Else clause shouldn't execute when the original case when is true. However it's grabbing that, and then still executing the case when inside of the else clause?
How can I fix this code to give me either fieldid = 2 OR fieldid = 35, but avoid globbing them both together which results in the name being duplicated?
EDIT
Here is the table structure:
table: subscribers_data
subscriberid (int) fieldid (int) data (text)
It uses an E-A-V structure so a sample record might be:
subscriberid fieldid data
1 2 John
1 3 Smith
1 35 John
1 36 Smith
with fieldid 2 and 35 being the custom field "First Name" (defined in a separate table) and fieldid 3 and 36 being "Last Name".
Here is the full view that I'm using:
select `ls`.`subscriberid` AS `id`,
left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) AS `user_id`,
ifnull(group_concat((
case when (`s`.`fieldid` = 2) then `s`.`data`
when (`s`.`fieldid` = 35) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `first_name`,
ifnull(group_concat((
case when (`s`.`fieldid` = 3) then `s`.`data`
when (`s`.`fieldid` = 36) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `last_name`,
ifnull(`ls`.`emailaddress`,_utf8'') AS `email_address`,
ifnull(group_concat((
case when (`s`.`fieldid` = 81) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `mobile_phone`,
ifnull(group_concat((
case when (`s`.`fieldid` = 100) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `sms_only`
from ((`list_subscribers` `ls`
join `lists` `l` on((`ls`.`listid` = `l`.`listid`)))
left join `subscribers_data` `s` on((`ls`.`subscriberid` = `s`.`subscriberid`)))
where (left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) regexp _utf8'[[:digit:]]+')
group by `ls`.`subscriberid`,`l`.`name`,`ls`.`emailaddress`
The view is being used as the Model for a Ruby on Rails application, so I'm using some creative hacking to fake out a "user_id" that Rails expects (we name the field list.name in the Lists table using a numeric ID that our front-end Rails app generates when we add a new user, so I'm extracting just this number to make the view look like a Rails-convention database table)
I am not a mysql guy, but in a sql server case statement, you could do it without the first 'else'
case
when fieldid = 2 then data
when fieldid = 35 then data
else null
end
Also, you seem to be returning the same 'data' field in both cases
Anything inside group_concat() doesn't have a way to see the context in which it's running. So, you have have two rows in a single group, one with fieldid=2 and second with fieldid=35, it will do the following:
processing row with fieldid=2...
s.fieldid = 2 is true, return s.data
processing row with fieldid=35...
s.fieldid = 2 is false, try the else part
s.fieldid = 35 is true, return s.data
This explains why is "John" returned multiple times. The only way to fix it is to run a different query outside of group_concat().
EDIT:
Ih you really have to do it this way, use something like this instead:
SELECT ...
min(CASE WHEN s.fieldid IN (2,35) THEN s.data ELSE NULL END) AS first_name
...
Alternatively you can do group_concat(DISTINCT ...) if the two values can't be different (otherwise you would get e.g. "John,Johny"). Why do you have two values for first_name/last_name though?