Case Statement in SQL Query Issue - sql

I'm trying to run a SQL query but an error happens when I run it.
Error:
[Code: -811, SQL State: 21000]
The result of a scalar fullselect, SELECT INTO statement, or VALUES INTO statement is more than one row..
SQLCODE=-811, SQLSTATE=21000, DRIVER=4.19.49
This is the SQL query that I am trying to run, I believe there is a problem with my CASE statement, I'm running out of solution. Please help, thanks a lot!
SELECT
ES.SHPMNT_REF,
(CASE
WHEN (ES.SERVICE_PROVIDER_NAME) IS NULL
THEN (SELECT BRDB.EXPORT_ONHAND.SERVICE_PROVIDER_NAME
FROM BRDB.EXPORT_ONHAND
WHERE BRDB.EXPORT_ONHAND.SHPMNT_REF = ES.SHPMNT_REF)
ELSE (ES.SERVICE_PROVIDER_NAME)
END) AS SP
FROM
BRDB.EXPORT_SHIPMENT ES
WHERE
ES.DATE_CREATE > CURRENT TIMESTAMP - 30 DAYS

I think this is what you are after. Joining on the table data you might need, then letting COALESCE check for null and get the other data if it is.
SELECT
ES.SHPMNT_REF,
COALESCE(ES.SERVICE_PROVIDER_NAME, OH.SERVICE_PROVIDER_NAME) AS SP
FROM BRDB.EXPORT_SHIPMENT ES
LEFT JOIN BRDB.EXPORT_ONHAND AS OH
ON ES.SHPMNT_REF = OH.SHPMNT_REF
WHERE
ES.DATE_CREATE > CURRENT TIMESTAMP - 30 DAYS

Maybe you should put inside the case:
THEN (SELECT TOP 1 BRDB.EXPORT_ONHAND.SERVICE_PROVIDER_NAME

The error is thrown because your subquery returns multiple values.
The best way would be joining the two table first and then get the value you need when the value is NULL.
That should work:
SELECT
ES.SHPMNT_REF
,CASE
WHEN ES.SERVICE_PROVIDER_NAME IS NULL
THEN EO.SERVICE_PROVIDER_NAME
ELSE ES.SERVICE_PROVIDER_NAME
END AS 'SP'
FROM BRDB.EXPORT_SHIPMENT ES
LEFT JOIN BRDB.EXPORT_ONHAND EO
ON ES.SHPMNT_REF = EO.SHPMNT_REF
WHERE ES.DATE_CREATE > CURRENT TIMESTAMP - 30 DAYS

Related

Not Exists clause -Query

I am using a NOT EXSITS clause in my query and wanted to make sure it was working correctly since I was getting lesser rows than expected.
SELECT DISTINCT offer.courier_uuid,
offer.region_uuid,
offer.offer_time_local,
Cast(scores.acceptance_rate AS DECIMAL(5, 3)) AS acceptance_rate
FROM integrated_delivery.trip_offer_fact offer
JOIN integrated_product.driver_score_v2 scores ON offer.courier_uuid = scores.courier_id
AND offer.region_uuid = scores.region_id
AND offer.business_day BETWEEN date '2019-04-04' AND date '2019-04-07'
AND scores.extract_dt = 20190331
AND NOT EXISTS
(SELECT NULL
FROM source_cassandra_courier_scheduling.assigned_block_by_id_v2 sched
JOIN source_cassandra_delivery.region r ON sched.region_id = r.id
WHERE offer.courier_uuid = sched.courier_id
AND offer.offer_time_local >= date_parse(date_format(AT_TIMEZONE("start",r.time_zone),'%Y-%m-%d %H:%i:%s'),'%Y-%m-%d %H:%i:%s')
AND offer.offer_time_local <= date_parse(date_format(AT_TIMEZONE("end",r.time_zone),'%Y-%m-%d %H:%i:%s'),'%Y-%m-%d %H:%i:%s')
AND element_at(sched.state,-1) = 'ASSIGNED')
ORDER BY 3
Is there anything wrong with my not exists clause? I am only asking since I am getting back lesser rows than expected. The not exists caluse contains a time conversion but i dont think that would affect anything.
I am trying to get all possible ids and their offer times that do NOT EXIST in the scheduled shifts table. I wanted confirm if the way I have the NOT EXISTS clause is correct or if there is something else I would need that would correctly pull all records that exist or not exist in that shed table?

Using SQL CASE Statement to replace Text with GROUP BY

I am Using SQL Server and i have the following Problem and i am hopping someone could help me.
I am getting this Error
Column 'TransactionsLine.Text' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I do not want to include Text in the GROUP BY Clause yes that makes the query run but the issue is there is other text in the field i do not want it grouping by i would just like to replace the Name with the Text for items matching the CASE
when i add Text to the group by i get this result.
43036 SPECIAL 73.0000
43036 SPECIAL 6.0000
Issue is exactly what the error says. You are selecting TransactionsLine.text which is not in the group by clause.
you probably want to put the case in your group by clause:
select StockItemCode as CODE,
(
case
when StockItems.Description like 'item%'
then TransactionsLine.text
else StockItems.Description
end
) as name,
SUM(ItemQuantity) as Sales
from Transactions
inner join TransactionsLine on Transactions.id = TransactionsLine.TransactionID
inner join StockItems on TransactionsLine.StockItemID = StockItems.id
where location = #location
and Department = 43
and Transactions.date between #FROM
and #TO
and TransactionTypeID in (3, 32)
group by StockItemCode,
case
when StockItems.Description like 'item%'
then TransactionsLine.text
else StockItems.Description
end

How should I create a temporary table when Union is used?

I can't use Dynamic Value bcoz of Error stating
"Lookup Error - SQL Server Database Error: Cannot perform an aggregate function on an expression containing an aggregate or a subquery."
Here is the Scenario :
Query 1
select pr.PRDCT,sum(CASE when pr.DEFINITIONCD='NOP' and pr.PERIOD='D' then pr.PRAMOUNT else 0 END)
as 'NOP D' from PRODUCTWISE_REPORT pr group by pr.PRDCT
Query 2
select DEFINITIONTYPECD from REPORTKPIMAPTXN where DEFINITIONTYPECD='NOP' and REPORTSEQ = (select REPORTSEQ from report_m where REPORTCD='MIS_Product_Wise_Report')
Query 2 returns 'NOP'
so when I put Query 2 in Query 1 for 'NOP', it throws Error
How to resolve this when I've to User Dynamic Query 2 ?
Your second query looks it could be rewritten with a join instead of that subselect. something like this. Of course you are still going to have some issues because your first query has two columns and this has only 1 column. You will have to add another column (can be NULL) to this query before the UNION will actually work.
select r.DEFINITIONTYPECD
from REPORTKPIMAPTXN r
INNER JOIN report_m m on m.REPORTSEQ = r.REPORTSEQ
where DEFINITIONTYPECD = 'NOP'
and r.REPORTCD = 'MIS_Product_Wise_Report'

If Else Statement within an inner join

I have a table jobs with a column StartDate that is often null. If it is not null this is what I want to inner join with a table quarters on, otherwise I want to inner join on some other conditions. This is sort of what I want:
INNER JOIN Quarters q
ON (IF j.StartDate IS NOT NULL (j. StartDate BETWEEN GETDATE() and q.EndDate)
ELSE **Some other condition**)
The error that comes up when this is run is that there is incorrect syntax near the keyword 'IF'
Does anyone know the correct syntax for this?
Thanks in advance for your help!
INNER JOIN Quarters q ON
(j.StartDate IS NOT NULL AND j. StartDate BETWEEN GETDATE() and q.EndDate)
OR
(j.StartDate IS NULL AND **Some other condition**)
The easiest way to handle this is just to treat it as a logical operation:
ON (j.StartDate IS NOT NULL
and j. StartDate BETWEEN GETDATE() and q.EndDate)
OR (some other condition)
Try
CASE WHEN j.StartDate IS NULL THEN somevalue ELSE some_other_value END
the syntax is
CASE WHEN some_boolean_expression THEN some_value_column_or_expression
WHEN some_boolean_expression THEN some_value_column_or_expression
... (repeat when as many times you need it)
ELSE some_value_column_or_expression
END
Note: Else can be ommited.
also see the links
http://www.craigsmullins.com/ssu_0899.htm
http://msdn.microsoft.com/en-us/library/ms181765.aspx

MySQL to PostgreSQL: GROUP BY issues

So I decided to try out PostgreSQL instead of MySQL but I am having some slight conversion problems. This was a query of mine that samples data from four tables and spit them out all in on result.
I am at a loss of how to convey this in PostgreSQL and specifically in Django but I am leaving that for another quesiton so bonus points if you can Django-fy it but no worries if you just pure SQL it.
SELECT links.id, links.created, links.url, links.title, user.username, category.title, SUM(votes.karma_delta) AS karma, SUM(IF(votes.user_id = 1, votes.karma_delta, 0)) AS user_vote
FROM links
LEFT OUTER JOIN `users` `user` ON (`links`.`user_id`=`user`.`id`)
LEFT OUTER JOIN `categories` `category` ON (`links`.`category_id`=`category`.`id`)
LEFT OUTER JOIN `votes` `votes` ON (`votes`.`link_id`=`links`.`id`)
WHERE (links.id = votes.link_id)
GROUP BY votes.link_id
ORDER BY (SUM(votes.karma_delta) - 1) / POW((TIMESTAMPDIFF(HOUR, links.created, NOW()) + 2), 1.5) DESC
LIMIT 20
The IF in the select was where my first troubles began. Seems it's an IF true/false THEN stuff ELSE other stuff END IF yet I can't get the syntax right. I tried to use Navicat's SQL builder but it constantly wanted me to place everything I had selected into the GROUP BY and that I think it all kinds of wrong.
What I am looking for in summary is to make this MySQL query work in PostreSQL. Thank you.
Current Progress
Just want to thank everybody for their help. This is what I have so far:
SELECT links_link.id, links_link.created, links_link.url, links_link.title, links_category.title, SUM(links_vote.karma_delta) AS karma, SUM(CASE WHEN links_vote.user_id = 1 THEN links_vote.karma_delta ELSE 0 END) AS user_vote
FROM links_link
LEFT OUTER JOIN auth_user ON (links_link.user_id = auth_user.id)
LEFT OUTER JOIN links_category ON (links_link.category_id = links_category.id)
LEFT OUTER JOIN links_vote ON (links_vote.link_id = links_link.id)
WHERE (links_link.id = links_vote.link_id)
GROUP BY links_link.id, links_link.created, links_link.url, links_link.title, links_category.title
ORDER BY links_link.created DESC
LIMIT 20
I had to make some table name changes and I am still working on my ORDER BY so till then we're just gonna cop out. Thanks again!
Have a look at this link GROUP BY
When GROUP BY is present, it is not
valid for the SELECT list expressions
to refer to ungrouped columns except
within aggregate functions, since
there would be more than one possible
value to return for an ungrouped
column.
You need to include all the select columns in the group by that are not part of the aggregate functions.
A few things:
Drop the backticks
Use a CASE statement instead of IF() CASE WHEN votes.use_id = 1 THEN votes.karma_delta ELSE 0 END
Change your timestampdiff to DATE_TRUNC('hour', now()) - DATE_TRUNC('hour', links.created) (you will need to then count the number of hours in the resulting interval. It would be much easier to compare timestamps)
Fix your GROUP BY and ORDER BY
Try to replace the IF with a case;
SUM(CASE WHEN votes.user_id = 1 THEN votes.karma_delta ELSE 0 END)
You also have to explicitly name every column or calculated column you use in the GROUP BY clause.